Merge branch 'devel'

master
Laxmikant Rashinkar 10 years ago
commit 8c316b46b8

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "librfxcodec"]
path = librfxcodec
url = git://github.com/neutrinolabs/librfxcodec

@ -5,6 +5,8 @@ EXTRA_DIST = \
file.h \
file_loc.h \
list.h \
list16.h \
fifo.h \
log.h \
os_calls.h \
os_calls.h \
@ -31,11 +33,14 @@ libcommon_la_SOURCES = \
d3des.c \
file.c \
list.c \
list16.c \
fifo.c \
log.c \
os_calls.c \
ssl_calls.c \
thread_calls.c \
trans.c
trans.c \
xrdp_tls.c
libcommon_la_LIBADD = \
-lcrypto \

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,21 +19,41 @@
#if !defined(ARCH_H)
#define ARCH_H
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
/* you can define L_ENDIAN or B_ENDIAN and NEED_ALIGN or NO_NEED_ALIGN
in the makefile to override */
/* check endianess */
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
#if !defined(__BYTE_ORDER) && defined(__linux__)
#include <endian.h>
#endif
#if defined(BYTE_ORDER)
#if BYTE_ORDER == BIG_ENDIAN
#define B_ENDIAN
#else
#define L_ENDIAN
#endif
#endif
#if !(defined(L_ENDIAN) || defined(B_ENDIAN))
#if defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || \
defined(__hppa__)
#define B_ENDIAN
#else
#define L_ENDIAN
#endif
#endif
#endif
/* check if we need to align data */
#if !(defined(NEED_ALIGN) || defined(NO_NEED_ALIGN))
#if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \
defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \
defined(__ia64__) || defined(__ppc__) || defined(__arm__)
#define NEED_ALIGN
#elif defined(__x86__) || defined(__x86_64__) || \
defined(__AMD64__) || defined(_M_IX86) || \
defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \
defined(__i386__)
#define NO_NEED_ALIGN
#else

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2012
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -72,7 +72,7 @@
(bpp==8?COLOR8(HRED(c),HGREEN(c),HBLUE(c)): \
(bpp==15?COLOR15(HRED(c),HGREEN(c),HBLUE(c)): \
(bpp==16?COLOR16(HRED(c),HGREEN(c),HBLUE(c)): \
(bpp==24?COLOR24BGR(HRED(c),HGREEN(c),HBLUE(c)):c) \
(bpp>=24?COLOR24BGR(HRED(c),HGREEN(c),HBLUE(c)):c) \
) \
) \
) \
@ -101,4 +101,10 @@
/* use crc for bitmap cache lookups */
#define USE_CRC
#define XR_RGB2BGR(a_ulColor) \
(a_ulColor & 0xFF000000) | \
((a_ulColor & 0x00FF0000) >> 16) | \
(a_ulColor & 0x0000FF00) | \
((a_ulColor & 0x000000FF) << 16)
#endif

@ -0,0 +1,169 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2004-2014
*
* Licensed 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.
*
* FIFO implementation to store pointer to data struct
*/
#include "fifo.h"
#include "os_calls.h"
/**
* Create new fifo data struct
*
* @return pointer to new FIFO or NULL if system out of memory
*****************************************************************************/
FIFO * APP_CC
fifo_create(void)
{
return (FIFO *) g_malloc(sizeof(FIFO), 1);
}
/**
* Delete specified FIFO
*****************************************************************************/
void APP_CC
fifo_delete(FIFO *self)
{
USER_DATA *udp;
if (!self)
return;
if (!self->head)
{
/* FIFO is empty */
g_free(self);
return;
}
if (self->head == self->tail)
{
/* only one item in FIFO */
if (self->auto_free)
g_free(self->head->item);
g_free(self->head);
g_free(self);
return;
}
/* more then one item in FIFO */
while (self->head)
{
udp = self->head;
if (self->auto_free)
g_free(udp->item);
self->head = udp->next;
g_free(udp);
}
g_free(self);
}
/**
* Add an item to the specified FIFO
*
* @param self FIFO to operate on
* @param item item to add to specified FIFO
*
* @return 0 on success, -1 on error
*****************************************************************************/
int APP_CC
fifo_add_item(FIFO *self, void *item)
{
USER_DATA *udp;
if (!self || !item)
return -1;
if ((udp = (USER_DATA *) g_malloc(sizeof(USER_DATA), 0)) == 0)
return -1;
udp->item = item;
udp->next = 0;
/* if fifo is empty, add to head */
if (!self->head)
{
self->head = udp;
self->tail = udp;
return 0;
}
/* add to tail */
self->tail->next = udp;
self->tail = udp;
return 0;
}
/**
* Return an item from top of FIFO
*
* @param self FIFO to operate on
*
* @return top item from FIFO or NULL if FIFO is empty
*****************************************************************************/
void * APP_CC
fifo_remove_item(FIFO *self)
{
void *item;
USER_DATA *udp;
if (!self || !self->head)
return 0;
if (self->head == self->tail)
{
/* only one item in FIFO */
item = self->head->item;
g_free(self->head);
self->head = 0;
self->tail = 0;
return item;
}
/* more then one item in FIFO */
udp = self->head;
item = self->head->item;
self->head = self->head->next;
g_free(udp);
return item;
}
/**
* Return FIFO status
*
* @param self FIFO to operate on
*
* @return true if FIFO is empty, false otherwise
*****************************************************************************/
int APP_CC
fifo_is_empty(FIFO *self)
{
if (!self)
return 1;
return (self->head == 0);
}

@ -0,0 +1,47 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2004-2014
*
* Licensed 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.
*
* FIFO implementation to store pointer to data struct
*/
#ifndef _FIFO_H
#define _FIFO_H
#include "arch.h"
typedef struct user_data USER_DATA;
struct user_data
{
USER_DATA *next;
void *item;
};
typedef struct fifo
{
USER_DATA *head;
USER_DATA *tail;
int auto_free;
} FIFO;
FIFO * APP_CC fifo_create(void);
void APP_CC fifo_delete(FIFO *self);
int APP_CC fifo_add_item(FIFO *self, void *item);
void * APP_CC fifo_remove_item(FIFO *self);
int APP_CC fifo_is_empty(FIFO *self);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,6 +24,8 @@
#include "file.h"
#include "parse.h"
#define FILE_MAX_LINE_BYTES 2048
/*****************************************************************************/
/* returns error
returns 0 if everything is ok
@ -32,7 +34,7 @@ static int APP_CC
l_file_read_sections(int fd, int max_file_size, struct list *names)
{
struct stream *s;
char text[256];
char text[FILE_MAX_LINE_BYTES];
char c;
int in_it;
int in_it_index;
@ -44,7 +46,7 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
g_file_seek(fd, 0);
in_it_index = 0;
in_it = 0;
g_memset(text, 0, 256);
g_memset(text, 0, FILE_MAX_LINE_BYTES);
list_clear(names);
make_stream(s);
init_stream(s, max_file_size);
@ -67,7 +69,7 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
list_add_item(names, (tbus)g_strdup(text));
in_it = 0;
in_it_index = 0;
g_memset(text, 0, 256);
g_memset(text, 0, FILE_MAX_LINE_BYTES);
}
else if (in_it)
{
@ -86,8 +88,9 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
}
/*****************************************************************************/
/* returns error */
static int APP_CC
file_read_line(struct stream *s, char *text)
file_read_line(struct stream *s, char *text, int text_bytes)
{
int i;
int skip_to_end;
@ -108,6 +111,7 @@ file_read_line(struct stream *s, char *text)
while (c != 10 && c != 13)
{
/* these mean skip the rest of the line */
if (c == '#' || c == '!' || c == ';')
{
skip_to_end = 1;
@ -117,6 +121,10 @@ file_read_line(struct stream *s, char *text)
{
text[i] = c;
i++;
if (i >= text_bytes)
{
return 1;
}
}
if (s_check_rem(s, 1))
@ -214,9 +222,10 @@ l_file_read_section(int fd, int max_file_size, const char *section,
struct list *names, struct list *values)
{
struct stream *s;
char text[512];
char name[512];
char value[512];
char *data;
char *text;
char *name;
char *value;
char *lvalue;
char c;
int in_it;
@ -225,11 +234,16 @@ l_file_read_section(int fd, int max_file_size, const char *section,
int index;
int file_size;
data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0);
text = data;
name = text + FILE_MAX_LINE_BYTES;
value = name + FILE_MAX_LINE_BYTES;
file_size = 32 * 1024; /* 32 K file size limit */
g_file_seek(fd, 0);
in_it_index = 0;
in_it = 0;
g_memset(text, 0, 512);
g_memset(text, 0, FILE_MAX_LINE_BYTES);
list_clear(names);
list_clear(values);
make_stream(s);
@ -249,10 +263,13 @@ l_file_read_section(int fd, int max_file_size, const char *section,
in_uint8(s, c);
if ((c == '#') || (c == ';'))
{
file_read_line(s, text);
if (file_read_line(s, text, FILE_MAX_LINE_BYTES) != 0)
{
break;
}
in_it = 0;
in_it_index = 0;
g_memset(text, 0, 512);
g_memset(text, 0, FILE_MAX_LINE_BYTES);
continue;
}
if (c == '[')
@ -263,8 +280,8 @@ l_file_read_section(int fd, int max_file_size, const char *section,
{
if (g_strcasecmp(section, text) == 0)
{
file_read_line(s, text);
while (file_read_line(s, text) == 0)
file_read_line(s, text, FILE_MAX_LINE_BYTES);
while (file_read_line(s, text, FILE_MAX_LINE_BYTES) == 0)
{
if (g_strlen(text) > 0)
{
@ -292,21 +309,27 @@ l_file_read_section(int fd, int max_file_size, const char *section,
}
free_stream(s);
g_free(data);
return 0;
}
in_it = 0;
in_it_index = 0;
g_memset(text, 0, 512);
g_memset(text, 0, FILE_MAX_LINE_BYTES);
}
else if (in_it)
{
text[in_it_index] = c;
in_it_index++;
if (in_it_index >= FILE_MAX_LINE_BYTES)
{
break;
}
}
}
}
free_stream(s);
g_free(data);
return 1;
}
@ -341,7 +364,7 @@ file_by_name_read_sections(const char *file_name, struct list *names)
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
return 1;
}
@ -382,7 +405,7 @@ file_by_name_read_section(const char *file_name, const char *section,
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
return 1;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2012
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -41,4 +41,28 @@
#define XRDP_LIB_PATH "/usr/local/lib/xrdp"
#endif
#if !defined(XRDP_LOG_PATH)
#define XRDP_LOG_PATH "/var/log"
#endif
#if !defined(XRDP_CHANSRV_STR)
#define XRDP_CHANSRV_STR "/tmp/.xrdp/xrdp_chansrv_socket_%d"
#endif
#if !defined(CHANSRV_PORT_OUT_STR)
#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d"
#endif
#if !defined(CHANSRV_PORT_IN_STR)
#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
#endif
#if !defined(CHANSRV_API_STR)
#define CHANSRV_API_STR "/tmp/.xrdp/xrdpapi_%d"
#endif
#if !defined(XRDP_X11RDP_STR)
#define XRDP_X11RDP_STR "/tmp/.xrdp/xrdp_display_%d"
#endif
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,11 +26,11 @@
/* list */
struct list
{
tbus* items;
int count;
int alloc_size;
int grow_by;
int auto_free;
tintptr* items;
int count;
int alloc_size;
int grow_by;
int auto_free;
};
struct list* APP_CC
@ -38,17 +38,17 @@ list_create(void);
void APP_CC
list_delete(struct list* self);
void APP_CC
list_add_item(struct list* self, tbus item);
tbus APP_CC
list_add_item(struct list* self, tintptr item);
tintptr APP_CC
list_get_item(struct list* self, int index);
void APP_CC
list_clear(struct list* self);
int APP_CC
list_index_of(struct list* self, tbus item);
list_index_of(struct list* self, tintptr item);
void APP_CC
list_remove_item(struct list* self, int index);
void APP_CC
list_insert_item(struct list* self, int index, tbus item);
list_insert_item(struct list* self, int index, tintptr item);
void APP_CC
list_append_list_strdup(struct list* self, struct list* dest, int start_index);
void APP_CC

@ -0,0 +1,188 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed 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.
*
* simple list
*/
#include "arch.h"
#include "os_calls.h"
#include "list16.h"
/*****************************************************************************/
struct list16 *APP_CC
list16_create(void)
{
struct list16 *self;
self = (struct list16 *)g_malloc(sizeof(struct list16), 0);
list16_init(self);
return self;
}
/*****************************************************************************/
void APP_CC
list16_delete(struct list16 *self)
{
if (self == 0)
{
return;
}
list16_deinit(self);
g_free(self);
}
/*****************************************************************************/
void APP_CC
list16_init(struct list16* self)
{
g_memset(self, 0, sizeof(struct list16));
self->max_count = 4;
self->items = self->mitems;
}
/*****************************************************************************/
void APP_CC
list16_deinit(struct list16* self)
{
if (self->items != self->mitems)
{
g_free(self->items);
}
}
/*****************************************************************************/
void APP_CC
list16_add_item(struct list16 *self, tui16 item)
{
tui16 *p;
int i;
if (self->count >= self->max_count)
{
i = self->max_count;
self->max_count += 4;
p = (tui16 *)g_malloc(sizeof(tui16) * self->max_count, 1);
g_memcpy(p, self->items, sizeof(tui16) * i);
if (self->items != self->mitems)
{
g_free(self->items);
}
self->items = p;
}
self->items[self->count] = item;
self->count++;
}
/*****************************************************************************/
tui16 APP_CC
list16_get_item(struct list16 *self, int index)
{
if (index < 0 || index >= self->count)
{
return 0;
}
return self->items[index];
}
/*****************************************************************************/
void APP_CC
list16_clear(struct list16 *self)
{
if (self->items != self->mitems)
{
g_free(self->items);
}
self->count = 0;
self->max_count = 4;
self->items = self->mitems;
}
/*****************************************************************************/
int APP_CC
list16_index_of(struct list16 *self, tui16 item)
{
int i;
for (i = 0; i < self->count; i++)
{
if (self->items[i] == item)
{
return i;
}
}
return -1;
}
/*****************************************************************************/
void APP_CC
list16_remove_item(struct list16 *self, int index)
{
int i;
if (index >= 0 && index < self->count)
{
for (i = index; i < (self->count - 1); i++)
{
self->items[i] = self->items[i + 1];
}
self->count--;
}
}
/*****************************************************************************/
void APP_CC
list16_insert_item(struct list16 *self, int index, tui16 item)
{
tui16 *p;
int i;
if (index == self->count)
{
list16_add_item(self, item);
return;
}
if (index >= 0 && index < self->count)
{
self->count++;
if (self->count > self->max_count)
{
i = self->max_count;
self->max_count += 4;
p = (tui16 *)g_malloc(sizeof(tui16) * self->max_count, 1);
g_memcpy(p, self->items, sizeof(tui16) * i);
if (self->items != self->mitems)
{
g_free(self->items);
}
self->items = p;
}
for (i = (self->count - 2); i >= index; i--)
{
self->items[i + 1] = self->items[i];
}
self->items[index] = item;
}
}

@ -0,0 +1,56 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed 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.
*
* simple list
*/
#if !defined(LIST16_H)
#define LIST16_H
#include "arch.h"
/* list */
struct list16
{
tui16* items;
int count;
int max_count;
tui16 mitems[4];
};
struct list16* APP_CC
list16_create(void);
void APP_CC
list16_delete(struct list16* self);
void APP_CC
list16_init(struct list16* self);
void APP_CC
list16_deinit(struct list16* self);
void APP_CC
list16_add_item(struct list16* self, tui16 item);
tui16 APP_CC
list16_get_item(struct list16* self, int index);
void APP_CC
list16_clear(struct list16* self);
int APP_CC
list16_index_of(struct list16* self, tui16 item);
void APP_CC
list16_remove_item(struct list16* self, int index);
void APP_CC
list16_insert_item(struct list16* self, int index, tui16 item);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,7 +36,7 @@
#include "log.h"
/* Here we store the current state and configuration of the log */
static struct log_config *staticLogConfig = NULL;
static struct log_config *g_staticLogConfig = NULL;
/* This file first start with all private functions.
In the end of the file the public functions is defined */
@ -284,6 +284,7 @@ internalReadConfiguration(const char *inFilename, const char *applicationName)
if (ret != LOG_STARTUP_OK)
{
g_file_close(fd);
return ret;
}
@ -296,11 +297,12 @@ internalReadConfiguration(const char *inFilename, const char *applicationName)
param_v->auto_free = 1;
/* read logging config */
ret = internal_config_read_logging(fd, staticLogConfig, param_n,
ret = internal_config_read_logging(fd, g_staticLogConfig, param_n,
param_v, applicationName);
if (ret != LOG_STARTUP_OK)
{
g_file_close(fd);
return ret;
}
@ -392,12 +394,12 @@ enum logReturns DEFAULT_CC
internalInitAndAllocStruct(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
staticLogConfig = g_malloc(sizeof(struct log_config), 1);
g_staticLogConfig = g_malloc(sizeof(struct log_config), 1);
if (staticLogConfig != NULL)
if (g_staticLogConfig != NULL)
{
staticLogConfig->fd = -1;
staticLogConfig->enable_syslog = 0;
g_staticLogConfig->fd = -1;
g_staticLogConfig->enable_syslog = 0;
ret = LOG_STARTUP_OK;
}
else
@ -418,7 +420,7 @@ log_start_from_param(const struct log_config *iniParams)
{
enum logReturns ret = LOG_GENERAL_ERROR;
if (staticLogConfig != NULL)
if (g_staticLogConfig != NULL)
{
log_message(LOG_LEVEL_ALWAYS, "Log already initialized");
return ret;
@ -440,24 +442,24 @@ log_start_from_param(const struct log_config *iniParams)
return ret;
}
staticLogConfig->enable_syslog = iniParams->enable_syslog;
staticLogConfig->fd = iniParams->fd;
staticLogConfig->log_file = g_strdup(iniParams->log_file);
staticLogConfig->log_level = iniParams->log_level;
staticLogConfig->log_lock = iniParams->log_lock;
staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
staticLogConfig->program_name = g_strdup(iniParams->program_name);
staticLogConfig->syslog_level = iniParams->syslog_level;
ret = internal_log_start(staticLogConfig);
g_staticLogConfig->enable_syslog = iniParams->enable_syslog;
g_staticLogConfig->fd = iniParams->fd;
g_staticLogConfig->log_file = g_strdup(iniParams->log_file);
g_staticLogConfig->log_level = iniParams->log_level;
g_staticLogConfig->log_lock = iniParams->log_lock;
g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
g_staticLogConfig->program_name = g_strdup(iniParams->program_name);
g_staticLogConfig->syslog_level = iniParams->syslog_level;
ret = internal_log_start(g_staticLogConfig);
if (ret != LOG_STARTUP_OK)
{
g_writeln("Could not start log");
if (staticLogConfig != NULL)
if (g_staticLogConfig != NULL)
{
g_free(staticLogConfig);
staticLogConfig = NULL;
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
}
}
@ -487,16 +489,16 @@ log_start(const char *iniFile, const char *applicationName)
if (ret == LOG_STARTUP_OK)
{
ret = internal_log_start(staticLogConfig);
ret = internal_log_start(g_staticLogConfig);
if (ret != LOG_STARTUP_OK)
{
g_writeln("Could not start log");
if (staticLogConfig != NULL)
if (g_staticLogConfig != NULL)
{
g_free(staticLogConfig);
staticLogConfig = NULL;
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
}
}
@ -517,12 +519,12 @@ enum logReturns DEFAULT_CC
log_end(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
ret = internal_log_end(staticLogConfig);
ret = internal_log_end(g_staticLogConfig);
if (staticLogConfig != NULL)
if (g_staticLogConfig != NULL)
{
g_free(staticLogConfig);
staticLogConfig = NULL;
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
return ret;
@ -539,13 +541,13 @@ log_message(const enum logLevels lvl, const char *msg, ...)
time_t now_t;
struct tm *now;
if (staticLogConfig == NULL)
if (g_staticLogConfig == NULL)
{
g_writeln("The log reference is NULL - log not initialized properly");
return LOG_ERROR_NO_CFG;
}
if (0 > staticLogConfig->fd && staticLogConfig->enable_syslog == 0)
if (0 > g_staticLogConfig->fd && g_staticLogConfig->enable_syslog == 0)
{
return LOG_ERROR_FILE_NOT_OPEN;
}
@ -584,7 +586,7 @@ log_message(const enum logLevels lvl, const char *msg, ...)
#endif
#endif
if (staticLogConfig->enable_syslog && (lvl <= staticLogConfig->syslog_level))
if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level))
{
/* log to syslog*/
/* %s fix compiler warning 'not a string literal' */
@ -592,19 +594,19 @@ log_message(const enum logLevels lvl, const char *msg, ...)
tc_get_threadid(), buff + 20);
}
if (lvl <= staticLogConfig->log_level)
if (lvl <= g_staticLogConfig->log_level)
{
/* log to console */
g_printf("%s", buff);
/* log to application logfile */
#ifdef LOG_ENABLE_THREAD
pthread_mutex_lock(&(staticLogConfig->log_lock));
pthread_mutex_lock(&(g_staticLogConfig->log_lock));
#endif
if (staticLogConfig->fd > 0)
if (g_staticLogConfig->fd > 0)
{
writereply = g_file_write(staticLogConfig->fd, buff, g_strlen(buff));
writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff));
if (writereply <= 0)
{
@ -613,7 +615,7 @@ log_message(const enum logLevels lvl, const char *msg, ...)
}
#ifdef LOG_ENABLE_THREAD
pthread_mutex_unlock(&(staticLogConfig->log_lock));
pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
#endif
}
@ -627,11 +629,11 @@ log_message(const enum logLevels lvl, const char *msg, ...)
char *DEFAULT_CC
getLogFile(char *replybuf, int bufsize)
{
if (staticLogConfig)
if (g_staticLogConfig)
{
if (staticLogConfig->log_file)
if (g_staticLogConfig->log_file)
{
g_strncpy(replybuf, staticLogConfig->log_file, bufsize);
g_strncpy(replybuf, g_staticLogConfig->log_file, bufsize);
}
else
{

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,23 +29,23 @@
/* logging levels */
enum logLevels
{
LOG_LEVEL_ALWAYS = 0,
LOG_LEVEL_ERROR,
LOG_LEVEL_WARNING,
LOG_LEVEL_INFO,
LOG_LEVEL_DEBUG
LOG_LEVEL_ALWAYS = 0,
LOG_LEVEL_ERROR,
LOG_LEVEL_WARNING,
LOG_LEVEL_INFO,
LOG_LEVEL_DEBUG
};
/* startup return values */
enum logReturns
{
LOG_STARTUP_OK = 0,
LOG_ERROR_MALLOC,
LOG_ERROR_NULL_FILE,
LOG_ERROR_FILE_OPEN,
LOG_ERROR_NO_CFG,
LOG_ERROR_FILE_NOT_OPEN,
LOG_GENERAL_ERROR
LOG_STARTUP_OK = 0,
LOG_ERROR_MALLOC,
LOG_ERROR_NULL_FILE,
LOG_ERROR_FILE_OPEN,
LOG_ERROR_NO_CFG,
LOG_ERROR_FILE_NOT_OPEN,
LOG_GENERAL_ERROR
};
#define SESMAN_CFG_LOGGING "Logging"
@ -65,14 +65,14 @@ enum logReturns
struct log_config
{
char* program_name;
char* log_file;
int fd;
unsigned int log_level;
int enable_syslog;
unsigned int syslog_level;
pthread_mutex_t log_lock;
pthread_mutexattr_t log_lock_attr;
char *program_name;
char *log_file;
int fd;
unsigned int log_level;
int enable_syslog;
unsigned int syslog_level;
pthread_mutex_t log_lock;
pthread_mutexattr_t log_lock_attr;
};
/* internal functions, only used in log.c if this ifdef is defined.*/
@ -86,7 +86,7 @@ struct log_config
*
*/
enum logReturns DEFAULT_CC
internal_log_start(struct log_config* l_cfg);
internal_log_start(struct log_config *l_cfg);
/**
*
@ -95,7 +95,7 @@ internal_log_start(struct log_config* l_cfg);
*
*/
enum logReturns DEFAULT_CC
internal_log_end(struct log_config* l_cfg);
internal_log_end(struct log_config *l_cfg);
/**
* Converts a log level to a string
@ -103,7 +103,7 @@ internal_log_end(struct log_config* l_cfg);
* @param str pointer where the string will be stored.
*/
void DEFAULT_CC
internal_log_lvl2str(const enum logLevels lvl, char* str);
internal_log_lvl2str(const enum logLevels lvl, char *str);
/**
*
@ -113,7 +113,7 @@ internal_log_lvl2str(const enum logLevels lvl, char* str);
*
*/
enum logLevels DEFAULT_CC
internal_log_text2level(char* s);
internal_log_text2level(char *s);
/**
* A function that init our struct that holds all state and
@ -133,9 +133,9 @@ internalInitAndAllocStruct(void);
* @return
*/
enum logReturns DEFAULT_CC
internal_config_read_logging(int file, struct log_config* lc,
struct list* param_n,
struct list* param_v,
internal_config_read_logging(int file, struct log_config *lc,
struct list *param_n,
struct list *param_v,
const char *applicationName);
/*End of internal functions*/
#endif
@ -147,7 +147,7 @@ internal_config_read_logging(int file, struct log_config* lc,
* @return LOG_STARTUP_OK on success
*/
enum logReturns DEFAULT_CC
log_start(const char* iniFile, const char* applicationName);
log_start(const char *iniFile, const char *applicationName);
/**
* An alternative log_start where the caller gives the params directly.
@ -171,7 +171,7 @@ log_end(void);
* @return
*/
enum logReturns DEFAULT_CC
log_message(const enum logLevels lvl, const char* msg, ...);
log_message(const enum logLevels lvl, const char *msg, ...);
/**
*
@ -181,7 +181,7 @@ log_message(const enum logLevels lvl, const char* msg, ...);
* @return 0 on success, 1 on failure
*
*/
int APP_CC text2bool(char* s);
int APP_CC text2bool(char *s);
/**
* This function returns the configured file name for the logfile

@ -471,8 +471,11 @@ g_tcp_socket(void)
{
option_value = 0;
option_len = sizeof(option_value);
setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
option_len);
if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
#endif
@ -484,8 +487,11 @@ g_tcp_socket(void)
{
option_value = 1;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len);
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
@ -498,8 +504,11 @@ g_tcp_socket(void)
{
option_value = 1024 * 32;
option_len = sizeof(option_value);
setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len);
if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value,
option_len) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n");
}
}
}
@ -768,7 +777,9 @@ g_tcp_local_connect(int sck, const char *port)
memset(&s, 0, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX;
strcpy(s.sun_path, port);
strncpy(s.sun_path, port, sizeof(s.sun_path));
s.sun_path[sizeof(s.sun_path) - 1] = 0;
return connect(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un));
#endif
}
@ -785,7 +796,10 @@ g_tcp_set_non_blocking(int sck)
#else
i = fcntl(sck, F_GETFL);
i = i | O_NONBLOCK;
fcntl(sck, F_SETFL, i);
if (fcntl(sck, F_SETFL, i) < 0)
{
log_message(LOG_LEVEL_ERROR, "g_tcp_set_non_blocking: fcntl() failed\n");
}
#endif
return 0;
}
@ -925,7 +939,9 @@ g_tcp_local_bind(int sck, const char *port)
memset(&s, 0, sizeof(struct sockaddr_un));
s.sun_family = AF_UNIX;
strcpy(s.sun_path, port);
strncpy(s.sun_path, port, sizeof(s.sun_path));
s.sun_path[sizeof(s.sun_path) - 1] = 0;
return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un));
#endif
}
@ -1421,7 +1437,12 @@ g_set_wait_obj(tbus obj)
return 1;
}
sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size);
if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0)
{
close(s);
return 1;
}
close(s);
return 0;
#endif
@ -1934,8 +1955,7 @@ g_mkdir(const char *dirname)
#if defined(_WIN32)
return 0;
#else
mkdir(dirname, S_IRWXU);
return 0;
return mkdir(dirname, S_IRWXU);
#endif
}
@ -2265,6 +2285,27 @@ g_strncmp(const char *c1, const char *c2, int len)
return strncmp(c1, c2, len);
}
/*****************************************************************************/
/* compare up to delim */
int APP_CC
g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
{
char c1;
char c2;
while (n > 0)
{
c1 = *s1++;
c2 = *s2++;
if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
{
return c1 - c2;
}
n--;
}
return c1 - c2;
}
/*****************************************************************************/
int APP_CC
g_strcasecmp(const char *c1, const char *c2)
@ -2906,9 +2947,13 @@ void APP_CC
g_clearenv(void)
{
#if defined(_WIN32)
#else
#if defined(BSD)
environ[0] = 0;
#else
environ = 0;
#endif
#endif
}
/*****************************************************************************/

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -115,6 +115,7 @@ char* APP_CC g_strdup(const char* in);
char* APP_CC g_strndup(const char* in, const unsigned int maxlen);
int APP_CC g_strcmp(const char* c1, const char* c2);
int APP_CC g_strncmp(const char* c1, const char* c2, int len);
int APP_CC g_strncmp_d(const char* c1, const char* c2, const char delim, int len);
int APP_CC g_strcasecmp(const char* c1, const char* c2);
int APP_CC g_strncasecmp(const char* c1, const char* c2, int len);
int APP_CC g_atoi(const char* str);

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,17 +36,17 @@
/* parser state */
struct stream
{
char* p;
char* end;
char* data;
int size;
/* offsets of various headers */
char* iso_hdr;
char* mcs_hdr;
char* sec_hdr;
char* rdp_hdr;
char* channel_hdr;
char* next_packet;
char *p;
char *end;
char *data;
int size;
/* offsets of various headers */
char *iso_hdr;
char *mcs_hdr;
char *sec_hdr;
char *rdp_hdr;
char *channel_hdr;
char *next_packet;
};
/******************************************************************************/
@ -63,76 +63,77 @@ struct stream
/******************************************************************************/
#define make_stream(s) \
(s) = (struct stream*)g_malloc(sizeof(struct stream), 1)
(s) = (struct stream*)g_malloc(sizeof(struct stream), 1)
/******************************************************************************/
#define init_stream(s, v) do \
{ \
if ((v) > (s)->size) \
{ \
g_free((s)->data); \
(s)->data = (char*)g_malloc((v), 0); \
(s)->size = (v); \
} \
(s)->p = (s)->data; \
(s)->end = (s)->data; \
(s)->next_packet = 0; \
if ((v) > (s)->size) \
{ \
g_free((s)->data); \
(s)->data = (char*)g_malloc((v), 0); \
(s)->size = (v); \
} \
(s)->p = (s)->data; \
(s)->end = (s)->data; \
(s)->next_packet = 0; \
} while (0)
/******************************************************************************/
#define free_stream(s) do \
{ \
if ((s) != 0) \
{ \
g_free((s)->data); \
} \
g_free((s)); \
if ((s) != 0) \
{ \
g_free((s)->data); \
} \
g_free((s)); \
} while (0)
/******************************************************************************/
#define s_push_layer(s, h, n) do \
{ \
(s)->h = (s)->p; \
(s)->p += (n); \
(s)->h = (s)->p; \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define s_pop_layer(s, h) \
(s)->p = (s)->h
(s)->p = (s)->h
/******************************************************************************/
#define s_mark_end(s) \
(s)->end = (s)->p
(s)->end = (s)->p
#define in_sint8(s, v) do \
{ \
(v) = *((signed char*)((s)->p)); \
(s)->p++; \
(v) = *((signed char*)((s)->p)); \
(s)->p++; \
} while (0)
/******************************************************************************/
#define in_uint8(s, v) do \
{ \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
} while (0)
/******************************************************************************/
#define in_uint8_peek(s, v) do { v = *s->p; } while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_sint16_le(s, v) do \
{ \
(v) = (signed short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
(v) = (signed short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
} while (0)
#else
#define in_sint16_le(s, v) do \
{ \
(v) = *((signed short*)((s)->p)); \
(s)->p += 2; \
(v) = *((signed short*)((s)->p)); \
(s)->p += 2; \
} while (0)
#endif
@ -140,49 +141,49 @@ struct stream
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint16_le(s, v) do \
{ \
(v) = (unsigned short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
(v) = (unsigned short) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) \
); \
(s)->p += 2; \
} while (0)
#else
#define in_uint16_le(s, v) do \
{ \
(v) = *((unsigned short*)((s)->p)); \
(s)->p += 2; \
(v) = *((unsigned short*)((s)->p)); \
(s)->p += 2; \
} while (0)
#endif
/******************************************************************************/
#define in_uint16_be(s, v) do \
{ \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint32_le(s, v) do \
{ \
(v) = (unsigned int) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) | \
(*((unsigned char*)((s)->p + 2)) << 16) | \
(*((unsigned char*)((s)->p + 3)) << 24) \
); \
(s)->p += 4; \
(v) = (unsigned int) \
( \
(*((unsigned char*)((s)->p + 0)) << 0) | \
(*((unsigned char*)((s)->p + 1)) << 8) | \
(*((unsigned char*)((s)->p + 2)) << 16) | \
(*((unsigned char*)((s)->p + 3)) << 24) \
); \
(s)->p += 4; \
} while (0)
#else
#define in_uint32_le(s, v) do \
{ \
(v) = *((unsigned int*)((s)->p)); \
(s)->p += 4; \
(v) = *((unsigned int*)((s)->p)); \
(s)->p += 4; \
} while (0)
#endif
@ -190,41 +191,41 @@ struct stream
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define in_uint64_le(s, v) do \
{ \
(v) = (tui64) \
( \
(((tui64)(*((unsigned char*)((s)->p + 0)))) << 0) | \
(((tui64)(*((unsigned char*)((s)->p + 1)))) << 8) | \
(((tui64)(*((unsigned char*)((s)->p + 2)))) << 16) | \
(((tui64)(*((unsigned char*)((s)->p + 3)))) << 24) | \
(((tui64)(*((unsigned char*)((s)->p + 4)))) << 32) | \
(((tui64)(*((unsigned char*)((s)->p + 5)))) << 40) | \
(((tui64)(*((unsigned char*)((s)->p + 6)))) << 48) | \
(((tui64)(*((unsigned char*)((s)->p + 7)))) << 56) \
); \
(s)->p += 8; \
(v) = (tui64) \
( \
(((tui64)(*((unsigned char*)((s)->p + 0)))) << 0) | \
(((tui64)(*((unsigned char*)((s)->p + 1)))) << 8) | \
(((tui64)(*((unsigned char*)((s)->p + 2)))) << 16) | \
(((tui64)(*((unsigned char*)((s)->p + 3)))) << 24) | \
(((tui64)(*((unsigned char*)((s)->p + 4)))) << 32) | \
(((tui64)(*((unsigned char*)((s)->p + 5)))) << 40) | \
(((tui64)(*((unsigned char*)((s)->p + 6)))) << 48) | \
(((tui64)(*((unsigned char*)((s)->p + 7)))) << 56) \
); \
(s)->p += 8; \
} while (0)
#else
#define in_uint64_le(s, v) do \
{ \
(v) = *((tui64*)((s)->p)); \
(s)->p += 8; \
(v) = *((tui64*)((s)->p)); \
(s)->p += 8; \
} while (0)
#endif
/******************************************************************************/
#define in_uint32_be(s, v) do \
{ \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) = *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
(v) <<= 8; \
(v) |= *((unsigned char*)((s)->p)); \
(s)->p++; \
} while (0)
/******************************************************************************/
@ -238,46 +239,46 @@ struct stream
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint16_le(s, v) do \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
} while (0)
#else
#define out_uint16_le(s, v) do \
{ \
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
(s)->p += 2; \
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
(s)->p += 2; \
} while (0)
#endif
/******************************************************************************/
#define out_uint16_be(s, v) do \
{ \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
} while (0)
/******************************************************************************/
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint32_le(s, v) do \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
} while (0)
#else
#define out_uint32_le(s, v) do \
{ \
*((unsigned int*)((s)->p)) = (v); \
(s)->p += 4; \
*((unsigned int*)((s)->p)) = (v); \
(s)->p += 4; \
} while (0)
#endif
@ -285,78 +286,78 @@ struct stream
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
#define out_uint64_le(s, v) do \
{ \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 32); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 40); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 48); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 56); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 0); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 32); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 40); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 48); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 56); \
(s)->p++; \
} while (0)
#else
#define out_uint64_le(s, v) do \
{ \
*((tui64*)((s)->p)) = (v); \
(s)->p += 8; \
*((tui64*)((s)->p)) = (v); \
(s)->p += 8; \
} while (0)
#endif
/******************************************************************************/
#define out_uint32_be(s, v) do \
{ \
*((s)->p) = (unsigned char)((v) >> 24); \
s->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
s->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
s->p++; \
*((s)->p) = (unsigned char)(v); \
(s)->p++; \
*((s)->p) = (unsigned char)((v) >> 24); \
s->p++; \
*((s)->p) = (unsigned char)((v) >> 16); \
s->p++; \
*((s)->p) = (unsigned char)((v) >> 8); \
s->p++; \
*((s)->p) = (unsigned char)(v); \
(s)->p++; \
} while (0)
/******************************************************************************/
#define in_uint8p(s, v, n) do \
{ \
(v) = (s)->p; \
(s)->p += (n); \
(v) = (s)->p; \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define in_uint8a(s, v, n) do \
{ \
g_memcpy((v), (s)->p, (n)); \
(s)->p += (n); \
g_memcpy((v), (s)->p, (n)); \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define in_uint8s(s, n) \
(s)->p += (n)
(s)->p += (n)
/******************************************************************************/
#define out_uint8p(s, v, n) do \
{ \
g_memcpy((s)->p, (v), (n)); \
(s)->p += (n); \
g_memcpy((s)->p, (v), (n)); \
(s)->p += (n); \
} while (0)
/******************************************************************************/
#define out_uint8a(s, v, n) \
out_uint8p((s), (v), (n))
out_uint8p((s), (v), (n))
/******************************************************************************/
#define out_uint8s(s, n) do \
{ \
g_memset((s)->p, 0, (n)); \
(s)->p += (n); \
g_memset((s)->p, 0, (n)); \
(s)->p += (n); \
} while (0)
/*

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2012
* Copyright (C) Jay Sorg 2012-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -400,7 +400,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
int error;
int len;
if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64))
if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) ||
((pri_len != 64) && (pri_len != 256)))
{
return 1;
}
@ -469,7 +470,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len,
int error;
int len;
if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64))
if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) ||
((pri_len != 64) && (pri_len != 256)))
{
return 1;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,12 +24,49 @@
#include "parse.h"
/*****************************************************************************/
struct trans *APP_CC
int APP_CC
trans_tls_recv(struct trans *self, void *ptr, int len)
{
if (self->tls == NULL)
{
return 1;
}
return xrdp_tls_read(self->tls, ptr, len);
}
/*****************************************************************************/
int APP_CC
trans_tls_send(struct trans *self, const void *data, int len)
{
if (self->tls == NULL)
{
return 1;
}
return xrdp_tls_write(self->tls, data, len);
}
/*****************************************************************************/
int APP_CC
trans_tcp_recv(struct trans *self, void *ptr, int len)
{
return g_tcp_recv(self->sck, ptr, len, 0);
}
/*****************************************************************************/
int APP_CC
trans_tcp_send(struct trans *self, const void *data, int len)
{
return g_tcp_send(self->sck, data, len, 0);
}
/*****************************************************************************/
struct trans *
APP_CC
trans_create(int mode, int in_size, int out_size)
{
struct trans *self = (struct trans *)NULL;
struct trans *self = (struct trans *) NULL;
self = (struct trans *)g_malloc(sizeof(struct trans), 1);
self = (struct trans *) g_malloc(sizeof(struct trans), 1);
if (self != NULL)
{
@ -38,6 +75,10 @@ trans_create(int mode, int in_size, int out_size)
make_stream(self->out_s);
init_stream(self->out_s, out_size);
self->mode = mode;
self->tls = 0;
/* assign tcp calls by default */
self->trans_recv = trans_tcp_recv;
self->trans_send = trans_tcp_send;
}
return self;
@ -68,6 +109,11 @@ trans_delete(struct trans *self)
g_free(self->listen_filename);
}
if (self->tls != 0)
{
xrdp_tls_delete(self->tls);
}
g_free(self);
}
@ -92,8 +138,7 @@ trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
/*****************************************************************************/
int APP_CC
trans_get_wait_objs_rw(struct trans *self,
tbus *robjs, int *rcount,
trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
tbus *wobjs, int *wcount)
{
if (self == 0)
@ -138,7 +183,7 @@ send_waiting(struct trans *self, int block)
if (g_tcp_can_send(self->sck, timeout))
{
bytes = (int) (temp_s->end - temp_s->p);
sent = g_tcp_send(self->sck, temp_s->p, bytes, 0);
sent = self->trans_send(self, temp_s->p, bytes);
if (sent > 0)
{
temp_s->p += sent;
@ -174,8 +219,8 @@ send_waiting(struct trans *self, int block)
int APP_CC
trans_check_wait_objs(struct trans *self)
{
tbus in_sck = (tbus)0;
struct trans *in_trans = (struct trans *)NULL;
tbus in_sck = (tbus) 0;
struct trans *in_trans = (struct trans *) NULL;
int read_bytes = 0;
int to_read = 0;
int read_so_far = 0;
@ -224,8 +269,10 @@ trans_check_wait_objs(struct trans *self)
in_trans->type1 = TRANS_TYPE_SERVER;
in_trans->status = TRANS_STATUS_UP;
in_trans->is_term = self->is_term;
g_strncpy(in_trans->addr, self->addr, sizeof(self->addr) - 1);
g_strncpy(in_trans->port, self->port, sizeof(self->port) - 1);
g_strncpy(in_trans->addr, self->addr,
sizeof(self->addr) - 1);
g_strncpy(in_trans->port, self->port,
sizeof(self->port) - 1);
if (self->trans_conn_in(self, in_trans) != 0)
{
@ -243,12 +290,12 @@ trans_check_wait_objs(struct trans *self)
{
if (g_tcp_can_recv(self->sck, 0))
{
read_so_far = (int)(self->in_s->end - self->in_s->data);
read_so_far = (int) (self->in_s->end - self->in_s->data);
to_read = self->header_size - read_so_far;
if (to_read > 0)
{
read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0);
read_bytes = self->trans_recv(self, self->in_s->end, to_read);
if (read_bytes == -1)
{
@ -275,7 +322,7 @@ trans_check_wait_objs(struct trans *self)
}
}
read_so_far = (int)(self->in_s->end - self->in_s->data);
read_so_far = (int) (self->in_s->end - self->in_s->data);
if (read_so_far == self->header_size)
{
@ -299,7 +346,6 @@ trans_check_wait_objs(struct trans *self)
return rv;
}
/*****************************************************************************/
int APP_CC
trans_force_read_s(struct trans *self, struct stream *in_s, int size)
@ -318,7 +364,9 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
{
return 1;
}
rcvd = g_tcp_recv(self->sck, in_s->end, size, 0);
rcvd = self->trans_recv(self, in_s->end, size);
if (rcvd == -1)
{
if (g_tcp_last_error_would_block(self->sck))
@ -380,7 +428,7 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
return 1;
}
size = (int)(out_s->end - out_s->data);
size = (int) (out_s->end - out_s->data);
total = 0;
if (send_waiting(self, 1) != 0)
@ -391,7 +439,7 @@ trans_force_write_s(struct trans *self, struct stream *out_s)
while (total < size)
{
sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0);
sent = self->trans_send(self, out_s->data + total, size - total);
if (sent == -1)
{
@ -455,7 +503,7 @@ trans_write_copy(struct trans *self)
}
out_s = self->out_s;
size = (int)(out_s->end - out_s->data);
size = (int) (out_s->end - out_s->data);
make_stream(wait_s);
init_stream(wait_s, size);
out_uint8a(wait_s, out_s->data, size);
@ -501,12 +549,18 @@ trans_connect(struct trans *self, const char *server, const char *port,
if (self->mode == TRANS_MODE_TCP) /* tcp */
{
self->sck = g_tcp_socket();
if (self->sck < 0)
return 1;
g_tcp_set_non_blocking(self->sck);
error = g_tcp_connect(self->sck, server, port);
}
else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
{
self->sck = g_tcp_local_socket();
if (self->sck < 0)
return 1;
g_tcp_set_non_blocking(self->sck);
error = g_tcp_local_connect(self->sck, port);
}
@ -537,6 +591,10 @@ trans_connect(struct trans *self, const char *server, const char *port,
}
/*****************************************************************************/
/**
* @return 0 on success, 1 on failure
*/
int APP_CC
trans_listen_address(struct trans *self, char *port, const char *address)
{
@ -548,6 +606,9 @@ trans_listen_address(struct trans *self, char *port, const char *address)
if (self->mode == TRANS_MODE_TCP) /* tcp */
{
self->sck = g_tcp_socket();
if (self->sck < 0)
return 1;
g_tcp_set_non_blocking(self->sck);
if (g_tcp_bind_address(self->sck, port, address) == 0)
@ -565,7 +626,11 @@ trans_listen_address(struct trans *self, char *port, const char *address)
g_free(self->listen_filename);
self->listen_filename = 0;
g_file_delete(port);
self->sck = g_tcp_local_socket();
if (self->sck < 0)
return 1;
g_tcp_set_non_blocking(self->sck);
if (g_tcp_local_bind(self->sck, port) == 0)
@ -574,7 +639,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
if (g_tcp_listen(self->sck) == 0)
{
g_chmod_hex(port, 0xffff);
g_chmod_hex(port, 0x0660);
self->status = TRANS_STATUS_UP; /* ok */
self->type1 = TRANS_TYPE_LISTENER; /* listener */
return 0;
@ -593,14 +658,15 @@ trans_listen(struct trans *self, char *port)
}
/*****************************************************************************/
struct stream *APP_CC
struct stream *
APP_CC
trans_get_in_s(struct trans *self)
{
struct stream *rv = (struct stream *)NULL;
struct stream *rv = (struct stream *) NULL;
if (self == NULL)
{
rv = (struct stream *)NULL;
rv = (struct stream *) NULL;
}
else
{
@ -611,14 +677,15 @@ trans_get_in_s(struct trans *self)
}
/*****************************************************************************/
struct stream *APP_CC
struct stream *
APP_CC
trans_get_out_s(struct trans *self, int size)
{
struct stream *rv = (struct stream *)NULL;
struct stream *rv = (struct stream *) NULL;
if (self == NULL)
{
rv = (struct stream *)NULL;
rv = (struct stream *) NULL;
}
else
{
@ -628,3 +695,43 @@ trans_get_out_s(struct trans *self, int size)
return rv;
}
/*****************************************************************************/
/* returns error */
int APP_CC
trans_set_tls_mode(struct trans *self, const char *key, const char *cert)
{
self->tls = xrdp_tls_create(self, key, cert);
if (self->tls == NULL)
{
g_writeln("trans_set_tls_mode: xrdp_tls_create malloc error");
return 1;
}
if (xrdp_tls_accept(self->tls) != 0)
{
g_writeln("trans_set_tls_mode: xrdp_tls_accept failed");
return 1;
}
/* assign tls functions */
self->trans_recv = trans_tls_recv;
self->trans_send = trans_tls_send;
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
trans_shutdown_tls_mode(struct trans *self)
{
if (self->tls != NULL)
{
return xrdp_tls_disconnect(self->tls);
}
/* assign callback back to tcp cal */
self->trans_recv = trans_tcp_recv;
self->trans_send = trans_tcp_send;
return 0;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,32 +35,59 @@
#define TRANS_STATUS_UP 1
struct trans; /* forward declaration */
struct xrdp_tls;
typedef int (*ttrans_data_in)(struct trans* self);
typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self);
typedef int (*tis_term)(void);
typedef int (DEFAULT_CC *ttrans_data_in)(struct trans* self);
typedef int (DEFAULT_CC *ttrans_conn_in)(struct trans* self,
struct trans* new_self);
typedef int (DEFAULT_CC *tis_term)(void);
typedef int (APP_CC *trans_recv) (struct trans *self, void *ptr, int len);
typedef int (APP_CC *trans_send) (struct trans *self, const void *data, int len);
struct trans
{
tbus sck; /* socket handle */
int mode; /* 1 tcp, 2 unix socket */
int status;
int type1; /* 1 listener 2 server 3 client */
ttrans_data_in trans_data_in;
ttrans_conn_in trans_conn_in;
void* callback_data;
int header_size;
struct stream* in_s;
struct stream* out_s;
char* listen_filename;
tis_term is_term; /* used to test for exit */
struct stream* wait_s;
char addr[256];
char port[256];
int no_stream_init_on_data_in;
int extra_flags; /* user defined */
tbus sck; /* socket handle */
int mode; /* 1 tcp, 2 unix socket */
int status;
int type1; /* 1 listener 2 server 3 client */
ttrans_data_in trans_data_in;
ttrans_conn_in trans_conn_in;
void* callback_data;
int header_size;
struct stream* in_s;
struct stream* out_s;
char* listen_filename;
tis_term is_term; /* used to test for exit */
struct stream* wait_s;
char addr[256];
char port[256];
int no_stream_init_on_data_in;
int extra_flags; /* user defined */
struct xrdp_tls *tls;
trans_recv trans_recv;
trans_send trans_send;
};
/* xrdp_tls */
struct xrdp_tls
{
void *ssl; /* SSL * */
void *ctx; /* SSL_CTX * */
char *cert;
char *key;
struct trans *trans;
};
/* xrdp_tls.c */
struct xrdp_tls *APP_CC
xrdp_tls_create(struct trans *trans, const char *key, const char *cert);
int APP_CC
xrdp_tls_accept(struct xrdp_tls *self);
int APP_CC
xrdp_tls_disconnect(struct xrdp_tls *self);
void APP_CC
xrdp_tls_delete(struct xrdp_tls *self);
struct trans* APP_CC
trans_create(int mode, int in_size, int out_size);
void APP_CC
@ -94,5 +121,13 @@ struct stream* APP_CC
trans_get_in_s(struct trans* self);
struct stream* APP_CC
trans_get_out_s(struct trans* self, int size);
int APP_CC
trans_set_tls_mode(struct trans *self, const char *key, const char *cert);
int APP_CC
trans_shutdown_tls_mode(struct trans *self);
int APP_CC
trans_tcp_force_read_s(struct trans *self, struct stream *in_s, int size);
int APP_CC
trans_force_write_s(struct trans *self, struct stream *out_s);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -106,7 +106,7 @@ struct xrdp_client_info
char client_addr[256];
char client_port[256];
int nego_sec_layer; /* 0, 1, 2 = RDP security layer, TLS , Negotiate */
int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */
int multimon; /* 0 = deny , 1 = allow */
int monitorCount; /* number of monitors detected (max = 16) */
struct monitor_info minfo[16]; /* client monitor data */
@ -121,6 +121,18 @@ struct xrdp_client_info
int mcs_connection_type;
int mcs_early_capability_flags;
int max_fastpath_frag_bytes;
int capture_code;
int capture_format;
char certificate[1024];
char key_file[1024];
/* X11 keyboard layout - inferred from keyboard type/subtype */
char model[16];
char layout[16];
char variant[16];
};
#endif

@ -3,7 +3,7 @@
* Miscellaneous protocol constants
*
* Copyright (C) Matthew Chapman 1999-2008
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
* Copyright (C) Kevin Zhou 2012
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -161,6 +161,7 @@
#define RDP_INPUT_VIRTKEY 2
#define RDP_INPUT_SCANCODE 4
#define RDP_INPUT_MOUSE 0x8001
#define RDP_INPUT_MOUSEX 0x8002
/* Device flags */
#define KBD_FLAG_RIGHT 0x0001
@ -560,6 +561,24 @@
#define RDP_CAPSET_LPOINTER 0x27
#define RDP_CAPLEN_LPOINTER 0x06
/* fastpath input */
#define FASTPATH_INPUT_SECURE_CHECKSUM 0x1
#define FASTPATH_INPUT_ENCRYPTED 0x2
#define FASTPATH_INPUT_ACTION_FASTPATH 0x0
#define FASTPATH_INPUT_ACTION_X224 0x3
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
#define FASTPATH_INPUT_EVENT_SYNC 0x3
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
/* fastpath output */
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
#define FASTPATH_OUTPUT_ACTION_X224 0x3

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2012-2013
* Copyright (C) Jay Sorg 2012-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -72,76 +72,76 @@
struct rail_icon_info
{
int bpp;
int width;
int height;
int cmap_bytes;
int mask_bytes;
int data_bytes;
char* mask;
char* cmap;
char* data;
int bpp;
int width;
int height;
int cmap_bytes;
int mask_bytes;
int data_bytes;
char *mask;
char *cmap;
char *data;
};
struct rail_window_rect
{
short left;
short top;
short right;
short bottom;
short left;
short top;
short right;
short bottom;
};
struct rail_notify_icon_infotip
{
int timeout;
int flags;
char* text;
char* title;
int timeout;
int flags;
char *text;
char *title;
};
struct rail_window_state_order
{
int owner_window_id;
int style;
int extended_style;
int show_state;
char* title_info;
int client_offset_x;
int client_offset_y;
int client_area_width;
int client_area_height;
int rp_content;
int root_parent_handle;
int window_offset_x;
int window_offset_y;
int window_client_delta_x;
int window_client_delta_y;
int window_width;
int window_height;
int num_window_rects;
struct rail_window_rect* window_rects;
int visible_offset_x;
int visible_offset_y;
int num_visibility_rects;
struct rail_window_rect* visibility_rects;
int owner_window_id;
int style;
int extended_style;
int show_state;
char *title_info;
int client_offset_x;
int client_offset_y;
int client_area_width;
int client_area_height;
int rp_content;
int root_parent_handle;
int window_offset_x;
int window_offset_y;
int window_client_delta_x;
int window_client_delta_y;
int window_width;
int window_height;
int num_window_rects;
struct rail_window_rect *window_rects;
int visible_offset_x;
int visible_offset_y;
int num_visibility_rects;
struct rail_window_rect *visibility_rects;
};
struct rail_notify_state_order
{
int version;
char* tool_tip;
struct rail_notify_icon_infotip infotip;
int state;
int icon_cache_entry;
int icon_cache_id;
struct rail_icon_info icon_info;
int version;
char *tool_tip;
struct rail_notify_icon_infotip infotip;
int state;
int icon_cache_entry;
int icon_cache_id;
struct rail_icon_info icon_info;
};
struct rail_monitored_desktop_order
{
int active_window_id;
int num_window_ids;
int* window_ids;
int active_window_id;
int num_window_ids;
int *window_ids;
};
#endif

@ -0,0 +1,269 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Idan Freiberg 2013-2014
*
* Licensed 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.
*
* transport layer security
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/ssl.h>
#include "os_calls.h"
#include "trans.h"
#include "ssl_calls.h"
/*****************************************************************************/
struct xrdp_tls *
APP_CC
xrdp_tls_create(struct trans *trans, const char *key, const char *cert)
{
struct xrdp_tls *self;
self = (struct xrdp_tls *) g_malloc(sizeof(struct xrdp_tls), 1);
if (self != NULL)
{
self->trans = trans;
self->cert = (char *) cert;
self->key = (char *) key;
}
return self;
}
/*****************************************************************************/
int APP_CC
xrdp_tls_print_error(char *func, SSL *connection, int value)
{
switch (SSL_get_error(connection, value))
{
case SSL_ERROR_ZERO_RETURN:
g_writeln("xrdp_tls_print_error: %s: Server closed TLS connection",
func);
return 1;
case SSL_ERROR_WANT_READ:
g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_READ");
return 0;
case SSL_ERROR_WANT_WRITE:
g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_WRITE");
return 0;
case SSL_ERROR_SYSCALL:
g_writeln("xrdp_tls_print_error: %s: I/O error", func);
return 1;
case SSL_ERROR_SSL:
g_writeln("xrdp_tls_print_error: %s: Failure in SSL library (protocol error?)",
func);
return 1;
default:
g_writeln("xrdp_tls_print_error: %s: Unknown error", func);
return 1;
}
}
/*****************************************************************************/
int APP_CC
xrdp_tls_accept(struct xrdp_tls *self)
{
int connection_status;
long options = 0;
/**
* SSL_OP_NO_SSLv2:
*
* We only want SSLv3 and TLSv1, so disable SSLv2.
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
*/
options |= SSL_OP_NO_SSLv2;
#if defined(SSL_OP_NO_COMPRESSION)
/**
* SSL_OP_NO_COMPRESSION:
*
* The Microsoft RDP server does not advertise support
* for TLS compression, but alternative servers may support it.
* This was observed between early versions of the FreeRDP server
* and the FreeRDP client, and caused major performance issues,
* which is why we're disabling it.
*/
options |= SSL_OP_NO_COMPRESSION;
#endif
/**
* SSL_OP_TLS_BLOCK_PADDING_BUG:
*
* The Microsoft RDP server does *not* support TLS padding.
* It absolutely needs to be disabled otherwise it won't work.
*/
options |= SSL_OP_TLS_BLOCK_PADDING_BUG;
/**
* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS:
*
* Just like TLS padding, the Microsoft RDP server does not
* support empty fragments. This needs to be disabled.
*/
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
self->ctx = SSL_CTX_new(SSLv23_server_method());
/* set context options */
SSL_CTX_set_mode(self->ctx,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_set_options(self->ctx, options);
SSL_CTX_set_read_ahead(self->ctx, 1);
if (self->ctx == NULL)
{
g_writeln("xrdp_tls_accept: SSL_CTX_new failed");
return 1;
}
if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
<= 0)
{
g_writeln("xrdp_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed");
return 1;
}
self->ssl = SSL_new(self->ctx);
if (self->ssl == NULL)
{
g_writeln("xrdp_tls_accept: SSL_new failed");
return 1;
}
if (SSL_use_certificate_file(self->ssl, self->cert, SSL_FILETYPE_PEM) <= 0)
{
g_writeln("xrdp_tls_accept: SSL_use_certificate_file failed");
return 1;
}
if (SSL_set_fd(self->ssl, self->trans->sck) < 1)
{
g_writeln("xrdp_tls_accept: SSL_set_fd failed");
return 1;
}
connection_status = SSL_accept(self->ssl);
if (connection_status <= 0)
{
if (xrdp_tls_print_error("SSL_accept", self->ssl, connection_status))
{
return 1;
}
}
g_writeln("xrdp_tls_accept: TLS connection accepted");
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_tls_disconnect(struct xrdp_tls *self)
{
int status = SSL_shutdown(self->ssl);
while (status != 1)
{
status = SSL_shutdown(self->ssl);
if (status <= 0)
{
if (xrdp_tls_print_error("SSL_shutdown", self->ssl, status))
{
return 1;
}
}
}
return 0;
}
/*****************************************************************************/
void APP_CC
xrdp_tls_delete(struct xrdp_tls *self)
{
if (self != NULL)
{
if (self->ssl)
SSL_free(self->ssl);
if (self->ctx)
SSL_CTX_free(self->ctx);
g_free(self);
}
}
/*****************************************************************************/
int APP_CC
xrdp_tls_read(struct xrdp_tls *tls, char *data, int length)
{
int status;
status = SSL_read(tls->ssl, data, length);
switch (SSL_get_error(tls->ssl, status))
{
case SSL_ERROR_NONE:
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
status = 0;
break;
default:
xrdp_tls_print_error("SSL_read", tls->ssl, status);
status = -1;
break;
}
return status;
}
/*****************************************************************************/
int APP_CC
xrdp_tls_write(struct xrdp_tls *tls, char *data, int length)
{
int status;
status = SSL_write(tls->ssl, data, length);
switch (SSL_get_error(tls->ssl, status))
{
case SSL_ERROR_NONE:
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
status = 0;
break;
default:
xrdp_tls_print_error("SSL_write", tls->ssl, status);
status = -1;
break;
}
return status;
}

@ -40,29 +40,21 @@ AC_ARG_ENABLE(jpeg, AS_HELP_STRING([--enable-jpeg],
[jpeg=true], [jpeg=false])
AM_CONDITIONAL(XRDP_JPEG, [test x$jpeg = xtrue])
AC_ARG_ENABLE(tjpeg, AS_HELP_STRING([--enable-tjpeg],
[Build turbo jpeg module(assumes /opt/libjpeg-turbo) (default: no)]),
[Build turbo jpeg module (default: no)]),
[tjpeg=true], [tjpeg=false])
AM_CONDITIONAL(XRDP_TJPEG, [test x$tjpeg = xtrue])
AC_ARG_ENABLE(simplesound, AS_HELP_STRING([--enable-simplesound],
[Build simple pulse audio interface (default: no)]),
[simplesound=true], [simplesound=false])
AM_CONDITIONAL(XRDP_SIMPLESOUND, [test x$simplesound = xtrue])
AC_ARG_ENABLE(fuse, AS_HELP_STRING([--enable-fuse],
[Build fuse(clipboard file / drive redir) (default: no)]),
[fuse=true], [fuse=false])
AM_CONDITIONAL(XRDP_FUSE, [test x$fuse = xtrue])
AC_ARG_ENABLE(loadpulsemodules, AS_HELP_STRING([--enable-loadpulsemodules],
[Build code to load pulse audio modules (default: no)]),
[loadpulsemodules=true], [loadpulsemodules=false])
AM_CONDITIONAL(XRDP_LOAD_PULSE_MODULES, [test x$loadpulsemodules = xtrue])
AC_ARG_ENABLE(xrdpvr, AS_HELP_STRING([--enable-xrdpvr],
[Build xrdpvr module (default: no)]),
[xrdpvr=true], [xrdpvr=false])
AM_CONDITIONAL(XRDP_XRDPVR, [test x$xrdpvr = xtrue])
AC_ARG_ENABLE(rfxcodec, AS_HELP_STRING([--enable-rfxcodec],
[Build using librfxcodec (default: no)]),
[rfxcodec=true], [rfxcodec=false])
AM_CONDITIONAL(XRDP_RFXCODEC, [test x$rfxcodec = xtrue])
AM_CONDITIONAL(GOT_PREFIX, test "x${prefix}" != "xNONE"])
@ -113,18 +105,34 @@ then
[#define _FILE_OFFSET_BITS 64])
fi
# checking for libpulse
if ! test -z "$enable_loadpulsemodules"
# checking for TurboJPEG
if ! test -z "$enable_tjpeg"
then
AC_CHECK_HEADER([pulse/util.h], [],
[AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])
fi
if test ! -z "$TURBOJPEG_PATH"
then
# env var TURBOJPEG_PATH has been defined, use that
AC_CHECK_HEADER([$TURBOJPEG_PATH/include/turbojpeg.h], [],
[AC_MSG_ERROR([could not find TurboJPEG in dir specified by env variable TURBOJPEG_PATH ($TURBOJPEG_PATH)])])
# checking for libpulse libpulse-simple
if ! test -z "$enable_simplesound"
AC_SUBST(TurboJpegIncDir, ["-I$TURBOJPEG_PATH/include"])
AC_SUBST(TurboJpegLibDir, ["-L$TURBOJPEG_PATH/lib -Wl,-rpath -Wl,$TURBOJPEG_PATH/lib"])
elif test -e /opt/libjpeg-turbo/lib64
then
# TurboJPEG has been installed to /opt on a 64 bit m/c
AC_SUBST(TurboJpegIncDir, ["-I/opt/libjpeg-turbo/include"])
AC_SUBST(TurboJpegLibDir, ["-L/opt/libjpeg-turbo/lib64 -Wl,-rpath -Wl,/opt/libjpeg-turbo/lib64"])
elif test -e /opt/libjpeg-turbo/lib32
then
AC_CHECK_HEADER([pulse/simple.h], [],
[AC_MSG_ERROR([please install libpulse-dev or libpulse-devel])])
# TurboJPEG has been installed to /opt on a 32 bit m/c
AC_SUBST(TurboJpegIncDir, ["-I/opt/libjpeg-turbo/include"])
AC_SUBST(TurboJpegLibDir, ["-L/opt/libjpeg-turbo/lib32 -Wl,-rpath -Wl,/opt/libjpeg-turbo/lib32"])
else
# check in default location
AC_CHECK_HEADER([/usr/include/turbojpeg.h], [],
[AC_MSG_ERROR([please install TurboJPEG ])])
AC_SUBST(TurboJpegIncDir, [""])
AC_SUBST(TurboJpegLibDir, [""])
fi
fi
# checking for Xlib, Xfixes
@ -133,6 +141,9 @@ AC_CHECK_HEADER([X11/Xlib.h], [],
AC_CHECK_HEADER([X11/extensions/Xfixes.h], [],
[AC_MSG_ERROR([please install libx11-dev and libxfixes-dev or libXfixes-devel])],
[#include <X11/Xlib.h>])
AC_CHECK_HEADER([X11/extensions/Xrandr.h], [],
[AC_MSG_ERROR([please install libxrandr-dev or libXrandr-devel])],
[#include <X11/Xlib.h>])
libdir="${libdir}/xrdp";
if test "x${prefix}" = "xNONE" ; then
@ -158,8 +169,9 @@ AC_CONFIG_FILES([Makefile
docs/man/Makefile
instfiles/Makefile
instfiles/pam.d/Makefile
instfiles/init.d/Makefile
instfiles/default/Makefile
instfiles/init.d/Makefile
instfiles/default/Makefile
instfiles/pulse/Makefile
genkeymap/Makefile
xrdpapi/Makefile
xrdpvr/Makefile

@ -116,6 +116,31 @@ Sets the time(in seconds) limit before a disconnected session is killed.
If set to \fI0\fR, automatic killing is disabled.
.br
.TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
Session allocation policy. By Default, a new session is created
for the combination <User,BitPerPixel> when using Xrdp, and
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
This behaviour can be changed by setting session policy to:
.br
.br
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
.br
\fBUBI\fR - session per <User,BitPerPixel,IPAddr>
.br
\fBUBC\fR - session per <User,BitPerPixel,Connection>
.br
\fBUBDI\fR - session per <User,BitPerPixel,DisplaySize,IPAddr>
.br
\fBUBDC\fR - session per <User,BitPerPixel,DisplaySize,Connection>
.br
.br
Note that the criteria <User,BitPerPixel> can not be turned off
and <DisplaySize> will always be checkt when for Xvnc connections.
.br
.SH "SECURITY"
The following parameters can be used in the \fB[Sessions]\fR section:

@ -45,8 +45,8 @@ int main(int argc, char **argv)
char text[256];
char *displayname = NULL;
char *outfname;
char *sections[5] = {"noshift", "shift", "altgr", "capslock", "shiftcapslock"};
int states[5] = {0, 1, 0x80, 2, 3};
char *sections[6] = {"noshift", "shift", "altgr", "shiftaltgr", "capslock", "shiftcapslock"};
int states[6] = {0, 1, 0x80, 0x81, 2, 3};
int i;
int idx;
int char_count;
@ -94,7 +94,7 @@ int main(int argc, char **argv)
e.display = dpy;
e.same_screen = True;
for (idx = 0; idx < 5; idx++) /* Sections and states */
for (idx = 0; idx < 6; idx++) /* Sections and states */
{
fprintf(outf, "[%s]\n", sections[idx]);
e.state = states[idx];

@ -1,35 +1,42 @@
Creating a new keymap file.
---------------------------
crating a new keymap file.
The names of the files are
The names of the files are of the format;
km-xxxx.ini
where the xxx is replaces ny the hex number of the layout of interest.
where the xxxx is replaced by the hex number of the layout of interest.
The files have 6 sections;
The files have 5 section
[noshift], [shift], [altgr], [shiftaltgr], [capslock], [shiftcapslock]
[noshift], [shift], [altgr], [capslock], [shiftcapslock]
In each section there are multiple lines for each key.
In each section there are multiple lines for each key
An example line looks like
An example line looks like;
Key10=49:49
In this line, 10 is the X11 scancode, the first 49 is the keysym value,
the second 49 if the unicode value of the key. This is the definition
for the 'noshift' '1' key on a en-us keyboard. In this case, the keysym
and the unicode value are the same. Here is an example where they are
not.
This is the definition for the backspace key.
and the unicode value are the same.
Here is an example where they are not;
This is the definition for the backspace key;
Key22=65288:8
And this is the star on the keypad
And this is the star on the keypad;
Key63=65450:42
To create a new file run xrdp-genkeymap filename
To create a new file run "xrdp-genkeymap <filename>"
Example: ./xrdp-genkeymap /etc/xrdp/km-0409.ini
Example ./xrdp-genkeymap /etc/xrdp/km-0409.ini
Note: You need to have enough rights to be able to write to the
/etc/xrdp directory.
Note: You need to have rights to the /etc/xrdp directory.
Alternatively, create the keymap file in a directory of your choice, then
copy or move it over to /etc/xrdp using sudo/su.

@ -5,7 +5,8 @@ xrdp.service
SUBDIRS = \
pam.d \
init.d \
default
default \
pulse
if HAVE_SYSTEMD
systemdsystemunit_DATA = \

@ -0,0 +1,3 @@
EXTRA_DIST = default.pa
pulsedir=$(sysconfdir)/xrdp/pulse
pulse_DATA = default.pa

@ -0,0 +1,7 @@
.nofail
.fail
load-module module-augment-properties
load-module module-xrdp-sink
load-module module-xrdp-source
load-module module-always-sink
load-module module-native-protocol-unix

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2012
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -31,19 +31,25 @@
#include "list.h"
#include "file.h"
#define MY_KEY_SIZE 512
/* this is the signature size in bytes */
#define TSSK_KEY_LENGTH 64
/* default to 512 bit key size, can set changed, set */
static int g_key_size_bits = 512;
static tui8 g_exponent[4] =
{
0x01, 0x00, 0x01, 0x00
};
/* 4 bytes public exponent */
static tui8 g_ppk_e[4] =
{
0x5B, 0x7B, 0x88, 0xC0
};
static tui8 g_ppk_n[72] =
/* 64 byte modulus */
static tui8 g_ppk_n[72] = /* 64 bytes + 8 bytes pad */
{
0x3D, 0x3A, 0x5E, 0xBD, 0x72, 0x43, 0x3E, 0xC9,
0x4D, 0xBB, 0xC1, 0x1E, 0x4A, 0xBA, 0x5F, 0xCB,
@ -56,7 +62,8 @@ static tui8 g_ppk_n[72] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static tui8 g_ppk_d[108] =
/* 64 bytes private exponent */
static tui8 g_ppk_d[108] = /* 64 bytes + 44 bytes pad */
{
0x87, 0xA7, 0x19, 0x32, 0xDA, 0x11, 0x87, 0x55,
0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xF8,
@ -74,40 +81,115 @@ static tui8 g_ppk_d[108] =
0x00, 0x00, 0x00, 0x00
};
static tui8 g_testkey[176] =
/* 512 bit proprietary certificate
dwVersion 0 4 bytes always 0x00000001
dwSigAlgId 4 4 bytes always 0x00000001
dwKeyAlgId 8 4 bytes always 0x00000001
wPublicKeyBlobType 12 2 bytes always 0x0006
wPublicKeyBlobLen 14 2 bytes 0x005C 92 bytes
magic 16 4 bytes always 0x31415352
keylen 20 4 bytes 0x0048 72 bytes
bitlen 24 4 bytes 0x0200 512 bits
datalen 28 4 bytes 0x003F 63 bytes
pubExp 32 4 bytes 0x00010001
modulus 36 72 bytes
wSignatureBlobType 108 2 bytes always 0x0008
wSignatureBlobLen 110 2 bytes 0x0048 72 bytes
SignatureBlob 112 72 bytes */
static tui8 g_testkey512[184] = /* 512 bit test key */
{
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0 */
0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x5c, 0x00,
0x52, 0x53, 0x41, 0x31, 0x48, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf,
0x01, 0x00, 0x01, 0x00, 0x79, 0x6f, 0xb4, 0xdf, /* 32 */
0xa6, 0x95, 0xb9, 0xa9, 0x61, 0xe3, 0xc4, 0x5e,
0xff, 0x6b, 0xd8, 0x81, 0x8a, 0x12, 0x4a, 0x93,
0x42, 0x97, 0x18, 0x93, 0xac, 0xd1, 0x3a, 0x38,
0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51,
0x3c, 0x68, 0x50, 0x19, 0x31, 0xb6, 0x84, 0x51, /* 64 */
0x79, 0xfb, 0x1c, 0xe7, 0xe3, 0x99, 0x20, 0xc7,
0x84, 0xdf, 0xd1, 0xaa, 0xb5, 0x15, 0xef, 0x47,
0x7e, 0xfc, 0x88, 0xeb, 0x29, 0xc3, 0x27, 0x5a,
0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x48, 0x00,
0x35, 0xf8, 0xfd, 0xaa, 0x00, 0x00, 0x00, 0x00, /* 96 */
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00,
0x32, 0x3b, 0xde, 0x6f, 0x18, 0x97, 0x1e, 0xc3,
0x6b, 0x2b, 0x2d, 0xe4, 0xfc, 0x2d, 0xa2, 0x8e,
0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d,
0x32, 0x3c, 0xf3, 0x1b, 0x24, 0x90, 0x57, 0x4d, /* 128 */
0x8e, 0xe4, 0x69, 0xfc, 0x16, 0x8d, 0x41, 0x92,
0x78, 0xc7, 0x9c, 0xb4, 0x26, 0xff, 0xe8, 0x3e,
0xa1, 0x8a, 0xf5, 0x57, 0xc0, 0x7f, 0x3e, 0x21,
0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd,
0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36
0x17, 0x32, 0x30, 0x6f, 0x79, 0xe1, 0x36, 0xcd, /* 160 */
0xb6, 0x8e, 0xbe, 0x57, 0x57, 0xd2, 0xa9, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* this is the installed signature */
char inst_pub_sig[] = "0x6a,0x41,0xb1,0x43,0xcf,0x47,0x6f,0xf1,0xe6,0xcc,0xa1,\
0x72,0x97,0xd9,0xe1,0x85,0x15,0xb3,0xc2,0x39,0xa0,0xa6,0x26,0x1a,0xb6,\
0x49,0x01,0xfa,0xa6,0xda,0x60,0xd7,0x45,0xf7,0x2c,0xee,0xe4,0x8e,0x64,\
0x2e,0x37,0x49,0xf0,0x4c,0x94,0x6f,0x08,0xf5,0x63,0x4c,0x56,0x29,0x55,\
0x5a,0x63,0x41,0x2c,0x20,0x65,0x95,0x99,0xb1,0x15,0x7c";
/* 2048 bit proprietary certificate
dwVersion 0 4 bytes always 0x00000001
dwSigAlgId 4 4 bytes always 0x00000001
dwKeyAlgId 8 4 bytes always 0x00000001
wPublicKeyBlobType 12 2 bytes always 0x0006
wPublicKeyBlobLen 14 2 bytes 0x011C 284 bytes
magic 16 4 bytes always 0x31415352
keylen 20 4 bytes 0x0108 264 bytes
bitlen 24 4 bytes 0x0800 2048 bits
datalen 28 4 bytes 0x00FF 255 bytes
pubExp 32 4 bytes 0x00010001
modulus 36 264 bytes
wSignatureBlobType 300 2 bytes always 0x0008
wSignatureBlobLen 302 2 bytes 0x0048 72 bytes
SignatureBlob 304 72 bytes */
static tui8 g_testkey2048[376] = /* 2048 bit test key */
{
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* 0 */
0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x1c, 0x01,
0x52, 0x53, 0x41, 0x31, 0x08, 0x01, 0x00, 0x00,
0x00, 0x08, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x13, 0x77, 0x6d, 0xd8, /* 32 */
0x7b, 0x6e, 0x6f, 0xb4, 0x27, 0x6d, 0x70, 0x3a,
0x97, 0x5f, 0xcb, 0x50, 0x9b, 0x13, 0x6b, 0xc7,
0xba, 0xdf, 0x73, 0x54, 0x17, 0x35, 0xf0, 0x09,
0x9e, 0x9d, 0x0b, 0x6a, 0x2c, 0x9f, 0xd1, 0x0c, /* 64 */
0xc6, 0x47, 0x83, 0xde, 0xca, 0x90, 0x20, 0xac,
0x70, 0x63, 0x9b, 0xb7, 0x49, 0x07, 0x0b, 0xf5,
0xf2, 0x38, 0x2a, 0x40, 0xff, 0xf1, 0xba, 0x97,
0x79, 0x3e, 0xd4, 0xd1, 0xf3, 0x41, 0x0f, 0x91, /* 96 */
0xfe, 0x1a, 0x86, 0xf4, 0x1b, 0xef, 0xcc, 0x29,
0xa3, 0x35, 0x6f, 0x60, 0xfa, 0x98, 0x53, 0x51,
0x80, 0x57, 0x15, 0x2f, 0xe1, 0x8b, 0xd7, 0x86,
0x15, 0x2d, 0xb5, 0xec, 0x7a, 0xdd, 0xc5, 0x1d, /* 128 */
0x1b, 0x88, 0x53, 0x67, 0x86, 0xe1, 0x6e, 0xcd,
0x4e, 0x2e, 0xfd, 0xd2, 0x49, 0x04, 0xfb, 0x1d,
0x95, 0xf0, 0xe9, 0x7f, 0x97, 0xa3, 0x1b, 0xb2,
0x92, 0x2e, 0x62, 0x2a, 0x96, 0xd4, 0xea, 0x18, /* 160 */
0x8e, 0x99, 0x41, 0xea, 0x83, 0xb5, 0xf1, 0x0e,
0xea, 0x53, 0x70, 0x99, 0xd7, 0x9e, 0x0c, 0x65,
0x2b, 0xf4, 0xdc, 0x0e, 0xe7, 0x9e, 0xce, 0x04,
0x25, 0x01, 0x88, 0xc4, 0xc1, 0xd2, 0xa4, 0x18, /* 192 */
0xc2, 0x8a, 0x52, 0x0f, 0x01, 0xb2, 0x71, 0x30,
0x44, 0x3f, 0x5b, 0x11, 0x2e, 0xe7, 0x53, 0xa0,
0xc8, 0x1f, 0x77, 0xaf, 0xb5, 0xbb, 0xaf, 0x12,
0xe8, 0x19, 0x0c, 0xf6, 0x1f, 0xa8, 0x3e, 0x11, /* 224 */
0x34, 0xe4, 0xac, 0x1c, 0x1c, 0x00, 0xbb, 0xb9,
0x2f, 0xbb, 0x81, 0x76, 0x4e, 0x46, 0xda, 0x73,
0x00, 0x82, 0x71, 0xa4, 0x62, 0xc3, 0xd4, 0x3f,
0xda, 0x34, 0x54, 0x27, 0xe3, 0xd0, 0x3a, 0x73, /* 256 */
0x2f, 0x99, 0xc4, 0x91, 0x56, 0x12, 0x98, 0xa8,
0x3b, 0x8d, 0x61, 0x83, 0x62, 0xb7, 0x20, 0x61,
0x4d, 0xc9, 0x41, 0xd1, 0x40, 0x02, 0x11, 0x4b,
0x63, 0x46, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00, /* 288 */
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x00,
0x00, 0x50, 0xb7, 0x75, 0xf3, 0x77, 0x99, 0xb2,
0xd3, 0xdd, 0xcd, 0x83, 0x6e, 0xdb, 0x0a, 0x29,
0x88, 0x05, 0xb5, 0x8a, 0x49, 0xd5, 0xa8, 0x5a, /* 320 */
0xc3, 0xb7, 0x18, 0xc2, 0x3c, 0x1e, 0xde, 0xd3,
0x8f, 0xdd, 0x21, 0x27, 0x84, 0xa0, 0xc8, 0x8d,
0x65, 0xce, 0x5d, 0x3d, 0x46, 0x65, 0x88, 0xfc,
0x35, 0x0a, 0x04, 0xa0, 0xda, 0xc1, 0xab, 0xbf, /* 352 */
0xcd, 0xf1, 0x7e, 0x71, 0x7b, 0xf8, 0x4a, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/*****************************************************************************/
static int APP_CC
@ -115,7 +197,7 @@ out_params(void)
{
g_writeln("");
g_writeln("xrdp rsa key gen utility examples");
g_writeln(" xrdp-keygen xrdp ['path and file name' | auto]");
g_writeln(" xrdp-keygen xrdp ['path and file name' | auto] [512 or 2048]");
g_writeln(" xrdp-keygen test");
g_writeln("");
return 0;
@ -131,37 +213,70 @@ sign_key(char *e_data, int e_len, char *n_data, int n_len,
char *md5_final;
void *md5;
if ((e_len != 4) || (n_len != 64) || (sign_len != 64))
if ((e_len != 4) || ((n_len != 64) && (n_len != 256)) || (sign_len != 64))
{
return 1;
}
key = (char *)g_malloc(176, 0);
md5_final = (char *)g_malloc(64, 0);
md5 = ssl_md5_info_create();
/* copy the test key */
g_memcpy(key, g_testkey, 176);
/* replace e and n */
g_memcpy(key + 32, e_data, 4);
g_memcpy(key + 36, n_data, 64);
ssl_md5_clear(md5);
/* the first 108 bytes */
ssl_md5_transform(md5, key, 108);
/* set the whole thing with 0xff */
g_memset(md5_final, 0xff, 64);
/* digest 16 bytes */
ssl_md5_complete(md5, md5_final);
/* set non 0xff array items */
md5_final[16] = 0;
md5_final[62] = 1;
md5_final[63] = 0;
/* encrypt */
ssl_mod_exp(sign_data, 64, md5_final, 64, (char *)g_ppk_n, 64,
(char *)g_ppk_d, 64);
/* cleanup */
ssl_md5_info_delete(md5);
g_free(key);
g_free(md5_final);
if (n_len == 64)
{
key = (char *)g_malloc(184, 0);
md5_final = (char *)g_malloc(64, 0);
md5 = ssl_md5_info_create();
/* copy the test key */
g_memcpy(key, g_testkey512, 184);
/* replace e and n */
g_memcpy(key + 32, e_data, e_len);
g_memcpy(key + 36, n_data, n_len);
ssl_md5_clear(md5);
/* the first 108 bytes */
ssl_md5_transform(md5, key, 108);
/* set the whole thing with 0xff */
g_memset(md5_final, 0xff, 64);
/* digest 16 bytes */
ssl_md5_complete(md5, md5_final);
/* set non 0xff array items */
md5_final[16] = 0;
md5_final[62] = 1;
md5_final[63] = 0;
/* encrypt */
ssl_mod_exp(sign_data, sign_len, md5_final, 64, (char *)g_ppk_n, 64,
(char *)g_ppk_d, 64);
/* cleanup */
ssl_md5_info_delete(md5);
g_free(key);
g_free(md5_final);
}
else if (n_len == 256)
{
key = (char *)g_malloc(376, 0);
md5_final = (char *)g_malloc(64, 0);
md5 = ssl_md5_info_create();
/* copy the test key */
g_memcpy(key, g_testkey2048, 376);
/* replace e and n */
g_memcpy(key + 32, e_data, e_len);
g_memcpy(key + 36, n_data, n_len);
ssl_md5_clear(md5);
/* the first 300 bytes */
ssl_md5_transform(md5, key, 300);
/* set the whole thing with 0xff */
g_memset(md5_final, 0xff, 64);
/* digest 16 bytes */
ssl_md5_complete(md5, md5_final);
/* set non 0xff array items */
md5_final[16] = 0;
md5_final[62] = 1;
md5_final[63] = 0;
/* encrypt */
ssl_mod_exp(sign_data, sign_len, md5_final, 64, (char *)g_ppk_n, 64,
(char *)g_ppk_d, 64);
/* cleanup */
ssl_md5_info_delete(md5);
g_free(key);
g_free(md5_final);
}
return 0;
}
@ -249,11 +364,12 @@ save_all(char *e_data, int e_len, char *n_data, int n_len,
fd = g_file_open(filename);
if (fd > 0)
if (fd != -1)
{
if (g_file_write(fd, "[keys]\n", 7) == -1)
{
g_writeln("problem writing to %s, maybe no rights", filename);
g_file_close(fd);
return 1;
}
@ -287,21 +403,21 @@ key_gen(const char *path_and_file_name)
int error;
e_data = (char *)g_exponent;
n_data = (char *)g_malloc(64, 0);
d_data = (char *)g_malloc(64, 0);
n_data = (char *)g_malloc(256, 0);
d_data = (char *)g_malloc(256, 0);
sign_data = (char *)g_malloc(64, 0);
e_len = 4;
n_len = 64;
d_len = 64;
n_len = g_key_size_bits / 8;
d_len = n_len;
sign_len = 64;
error = 0;
g_writeln("");
g_writeln("Generating %d bit rsa key...", MY_KEY_SIZE);
g_writeln("Generating %d bit rsa key...", g_key_size_bits);
g_writeln("");
if (error == 0)
{
error = ssl_gen_key_xrdp1(MY_KEY_SIZE, e_data, e_len, n_data, n_len,
error = ssl_gen_key_xrdp1(g_key_size_bits, e_data, e_len, n_data, n_len,
d_data, d_len);
if (error != 0)
@ -340,84 +456,58 @@ key_gen(const char *path_and_file_name)
}
/*****************************************************************************/
/* returns boolean */
static int APP_CC
key_gen_run_it(void)
key_gen_auto(void)
{
int fd;
int index;
int rv;
struct list *names;
struct list *values;
char *name;
char *value;
if (!g_file_exist("/etc/xrdp/rsakeys.ini"))
{
return 1;
}
if (g_file_get_size("/etc/xrdp/rsakeys.ini") < 10)
{
return 1;
}
fd = g_file_open("/etc/xrdp/rsakeys.ini");
if (fd < 0)
{
return 1;
}
rv = 0;
names = list_create();
names->auto_free = 1;
values = list_create();
values->auto_free = 1;
if (file_read_section(fd, "keys", names, values) == 0)
{
for (index = 0; index < names->count; index++)
{
name = (char *)list_get_item(names, index);
value = (char *)list_get_item(values, index);
if (g_strcasecmp(name, "pub_sig") == 0)
{
if (g_strcasecmp(value, inst_pub_sig) == 0)
{
rv = 1;
}
}
}
}
else
{
g_writeln("error reading keys section of rsakeys.ini");
}
list_delete(names);
list_delete(values);
g_file_close(fd);
return rv;
return key_gen("/etc/xrdp/rsakeys.ini");
}
/*****************************************************************************/
static int APP_CC
key_gen_auto(void)
key_test512(void)
{
if (key_gen_run_it())
{
return key_gen("/etc/xrdp/rsakeys.ini");
}
char *md5_final;
char *sig;
void *md5;
g_writeln("xrdp-keygen does not need to run");
md5_final = (char *)g_malloc(64, 0);
sig = (char *)g_malloc(64, 0);
md5 = ssl_md5_info_create();
g_writeln("original key is:");
g_hexdump((char *)g_testkey512, 184);
g_writeln("original exponent is:");
g_hexdump((char *)g_testkey512 + 32, 4);
g_writeln("original modulus is:");
g_hexdump((char *)g_testkey512 + 36, 64);
g_writeln("original signature is:");
g_hexdump((char *)g_testkey512 + 112, 64);
ssl_md5_clear(md5);
ssl_md5_transform(md5, (char *)g_testkey512, 108);
g_memset(md5_final, 0xff, 64);
ssl_md5_complete(md5, md5_final);
g_writeln("md5 hash of first 108 bytes of this key is:");
g_hexdump(md5_final, 16);
md5_final[16] = 0;
md5_final[62] = 1;
md5_final[63] = 0;
ssl_mod_exp(sig, 64, md5_final, 64, (char *)g_ppk_n, 64, (char *)g_ppk_d, 64);
g_writeln("produced signature(this should match original "
"signature above) is:");
g_hexdump(sig, 64);
g_memset(md5_final, 0, 64);
ssl_mod_exp(md5_final, 64, (char *)g_testkey512 + 112, 64, (char *)g_ppk_n, 64,
(char *)g_ppk_e, 4);
g_writeln("decrypted hash of first 108 bytes of this key is:");
g_hexdump(md5_final, 64);
ssl_md5_info_delete(md5);
g_free(md5_final);
g_free(sig);
return 0;
}
/*****************************************************************************/
static int APP_CC
key_test(void)
key_test2048(void)
{
char *md5_final;
char *sig;
@ -427,28 +517,28 @@ key_test(void)
sig = (char *)g_malloc(64, 0);
md5 = ssl_md5_info_create();
g_writeln("original key is:");
g_hexdump((char *)g_testkey, 176);
g_hexdump((char *)g_testkey2048, 376);
g_writeln("original exponent is:");
g_hexdump((char *)g_testkey + 32, 4);
g_hexdump((char *)g_testkey2048 + 32, 4);
g_writeln("original modulus is:");
g_hexdump((char *)g_testkey + 36, 64);
g_hexdump((char *)g_testkey2048 + 36, 256);
g_writeln("original signature is:");
g_hexdump((char *)g_testkey + 112, 64);
g_hexdump((char *)g_testkey2048 + 304, 64);
ssl_md5_clear(md5);
ssl_md5_transform(md5, (char *)g_testkey, 108);
ssl_md5_transform(md5, (char *)g_testkey2048, 300);
g_memset(md5_final, 0xff, 64);
ssl_md5_complete(md5, md5_final);
g_writeln("md5 hash of first 108 bytes of this key is:");
g_writeln("md5 hash of first 300 bytes of this key is:");
g_hexdump(md5_final, 16);
md5_final[16] = 0;
md5_final[62] = 1;
md5_final[63] = 0;
ssl_mod_exp(sig, 64, md5_final, 64, (char *)g_ppk_n, 64, (char *)g_ppk_d, 64);
g_writeln("produced signature(this should match original \
signature above) is:");
g_writeln("produced signature(this should match original "
"signature above) is:");
g_hexdump(sig, 64);
g_memset(md5_final, 0, 64);
ssl_mod_exp(md5_final, 64, (char *)g_testkey + 112, 64, (char *)g_ppk_n, 64,
ssl_mod_exp(md5_final, 64, (char *)g_testkey2048 + 304, 64, (char *)g_ppk_n, 64,
(char *)g_ppk_e, 4);
g_writeln("decrypted hash of first 108 bytes of this key is:");
g_hexdump(md5_final, 64);
@ -468,6 +558,15 @@ main(int argc, char **argv)
{
if (argc > 2)
{
if (argc > 3)
{
g_key_size_bits = g_atoi(argv[3]);
if ((g_key_size_bits != 512) && (g_key_size_bits != 2048))
{
out_params();
return 0;
}
}
if (g_strcasecmp(argv[2], "auto") == 0)
{
if (g_getuid() != 0)
@ -490,7 +589,13 @@ main(int argc, char **argv)
}
else if (g_strcasecmp(argv[1], "test") == 0)
{
return key_test();
g_writeln("");
g_writeln("testing 512 bit key");
key_test512();
g_writeln("");
g_writeln("testing 2048 bit key");
key_test2048();
return 0;
}
}

@ -0,0 +1 @@
Subproject commit de6a45cba607b902da704304fa3de8ddd3d15239

@ -18,8 +18,8 @@ endif
if XRDP_TJPEG
EXTRA_DEFINES += -DXRDP_JPEG -DXRDP_TJPEG
EXTRA_INCLUDES += -I/opt/libjpeg-turbo/include
EXTRA_FLAGS += -L/opt/libjpeg-turbo/lib -Wl,-rpath -Wl,/opt/libjpeg-turbo/lib
EXTRA_INCLUDES += @TurboJpegIncDir@
EXTRA_FLAGS += @TurboJpegLibDir@
EXTRA_LIBS += -lturbojpeg
else
if XRDP_JPEG
@ -59,7 +59,9 @@ libxrdp_la_SOURCES = \
xrdp_bitmap32_compress.c \
xrdp_jpeg_compress.c \
xrdp_orders_rail.c \
xrdp_mppc_enc.c
xrdp_mppc_enc.c \
xrdp_fastpath.c \
xrdp_caps.c
libxrdp_la_LDFLAGS = \
$(EXTRA_FLAGS)

@ -21,6 +21,12 @@
#include "libxrdp.h"
#include "xrdp_orders_rail.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
/******************************************************************************/
struct xrdp_session *EXPORT_CC
libxrdp_init(tbus id, struct trans *trans)
@ -29,6 +35,7 @@ libxrdp_init(tbus id, struct trans *trans)
session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1);
session->id = id;
session->trans = trans;
session->rdp = xrdp_rdp_create(session, trans);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
@ -61,7 +68,103 @@ libxrdp_disconnect(struct xrdp_session *session)
int EXPORT_CC
libxrdp_process_incomming(struct xrdp_session *session)
{
return xrdp_rdp_incoming((struct xrdp_rdp *)session->rdp);
int rv;
rv = xrdp_rdp_incoming((struct xrdp_rdp *)(session->rdp));
return rv;
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_get_pdu_bytes(const char *aheader)
{
int rv;
const tui8 *header;
rv = -1;
header = (const tui8 *) aheader;
if (header[0] == 0x03)
{
/* TPKT */
rv = (header[2] << 8) | header[3];
}
else if (header[0] == 0x30)
{
/* TSRequest (NLA) */
if (header[1] & 0x80)
{
if ((header[1] & ~(0x80)) == 1)
{
rv = header[2];
rv += 3;
}
else if ((header[1] & ~(0x80)) == 2)
{
rv = (header[2] << 8) | header[3];
rv += 4;
}
else
{
g_writeln("libxrdp_get_pdu_bytes: error TSRequest!");
return -1;
}
}
else
{
rv = header[1];
rv += 2;
}
}
else
{
/* Fast-Path */
if (header[1] & 0x80)
{
rv = ((header[1] & 0x7F) << 8) | header[2];
}
else
{
rv = header[1];
}
}
return rv;
}
/******************************************************************************/
/* only used durring connection */
struct stream * APP_CC
libxrdp_force_read(struct trans* trans)
{
int bytes;
struct stream *s;
s = trans->in_s;
init_stream(s, 32 * 1024);
if (trans_force_read(trans, 4) != 0)
{
g_writeln("libxrdp_force_read: error");
return 0;
}
bytes = libxrdp_get_pdu_bytes(s->data);
if (bytes < 1)
{
g_writeln("libxrdp_force_read: error");
return 0;
}
if (bytes > 32 * 1024)
{
g_writeln("libxrdp_force_read: error");
return 0;
}
if (trans_force_read(trans, bytes - 4) != 0)
{
g_writeln("libxrdp_force_read: error");
return 0;
}
return s;
}
/******************************************************************************/
@ -73,9 +176,15 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
int code;
int term;
int dead_lock_counter;
int do_read;
struct xrdp_rdp *rdp;
struct stream *ls;
do_read = s == 0;
if (do_read && session->up_and_running)
{
g_writeln("libxrdp_process_data: error logic");
return 1;
}
if (session->in_process_data != 0)
{
g_writeln("libxrdp_process_data: error reentry");
@ -83,14 +192,6 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
}
session->in_process_data++;
ls = 0;
if (s == 0)
{
make_stream(ls);
init_stream(ls, 8192 * 4);
s = ls;
}
term = 0;
cont = 1;
rv = 0;
@ -105,13 +206,36 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
if (session->is_term())
{
term = 1;
break;
}
}
code = 0;
if (do_read)
{
if (s == 0)
{
s = libxrdp_force_read(session->trans);
}
else
{
if ((s->next_packet == 0) || (s->next_packet >= s->end))
{
s = libxrdp_force_read(session->trans);
}
}
if (s == 0)
{
g_writeln("libxrdp_process_data: libxrdp_force_read failed");
rv = 1;
break;
}
}
if (xrdp_rdp_recv(rdp, s, &code) != 0)
{
g_writeln("libxrdp_process_data: xrdp_rdp_recv failed");
rv = 1;
break;
}
@ -121,39 +245,33 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
switch (code)
{
case -1:
xrdp_rdp_send_demand_active(rdp);
/* send Monitor Layout PDU for multimon */
if (session->client_info->monitorCount > 0 &&
session->client_info->multimon == 1)
{
DEBUG(("sending monitor layout pdu"));
if (xrdp_rdp_send_monitorlayout(rdp) != 0)
{
g_writeln("xrdp_rdp_send_monitorlayout: error");
}
}
xrdp_caps_send_demand_active(rdp);
session->up_and_running = 0;
break;
case 0:
dead_lock_counter++;
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active(rdp, s);
xrdp_caps_process_confirm_active(rdp, s);
break;
case RDP_PDU_DATA: /* 7 */
if (xrdp_rdp_process_data(rdp, s) != 0)
{
DEBUG(("libxrdp_process_data returned non zero"));
cont = 0;
term = 1;
}
break;
case 2: /* FASTPATH_INPUT_EVENT */
if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0)
{
DEBUG(("libxrdp_process_data returned non zero"));
cont = 0;
term = 1;
}
break;
default:
g_writeln("unknown in libxrdp_process_data");
g_writeln("unknown in libxrdp_process_data: code= %d", code);
dead_lock_counter++;
break;
}
@ -169,16 +287,10 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
if (cont)
{
cont = (s->next_packet != 0) &&
(s->next_packet < s->end);
cont = (s->next_packet != 0) && (s->next_packet < s->end);
}
}
if (s == ls)
{
free_stream(s);
}
session->in_process_data--;
return rv;
@ -198,11 +310,27 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
}
DEBUG(("libxrdp_send_palette sending palette"));
/* clear orders */
libxrdp_orders_force_send(session);
make_stream(s);
init_stream(s, 8192);
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
LLOGLN(10, ("libxrdp_send_palette: fastpath"));
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
free_stream(s);
return 1;
}
}
else {
LLOGLN(10, ("libxrdp_send_palette: slowpath"));
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
}
/* TS_UPDATE_PALETTE_DATA */
out_uint16_le(s, RDP_UPDATE_PALETTE);
out_uint16_le(s, 0);
out_uint16_le(s, 256); /* # of colors */
@ -217,8 +345,22 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
}
s_mark_end(s);
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_UPDATE);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_PALETTE) != 0)
{
free_stream(s);
return 1;
}
}
else
{
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_UPDATE);
}
free_stream(s);
/* send the orders palette too */
libxrdp_orders_init(session);
libxrdp_orders_send_palette(session, palette, 0);
@ -482,20 +624,46 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
}
make_stream(s);
init_stream(s, 8192);
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
if ((session->client_info->pointer_flags & 1) == 0)
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
out_uint16_le(s, RDP_POINTER_COLOR);
out_uint16_le(s, 0); /* pad */
data_bytes = 3072;
LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
free_stream(s);
return 1;
}
if ((session->client_info->pointer_flags & 1) == 0)
{
data_bytes = 3072;
}
else
{
data_bytes = ((bpp + 7) / 8) * 32 * 32;
out_uint16_le(s, bpp);
}
}
else
else /* slowpath */
{
out_uint16_le(s, RDP_POINTER_POINTER);
out_uint16_le(s, 0); /* pad */
out_uint16_le(s, bpp);
data_bytes = ((bpp + 7) / 8) * 32 * 32;
LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
if ((session->client_info->pointer_flags & 1) == 0)
{
out_uint16_le(s, RDP_POINTER_COLOR);
out_uint16_le(s, 0); /* pad */
data_bytes = 3072;
}
else
{
out_uint16_le(s, RDP_POINTER_POINTER);
out_uint16_le(s, 0); /* pad */
out_uint16_le(s, bpp);
data_bytes = ((bpp + 7) / 8) * 32 * 32;
}
}
out_uint16_le(s, cache_idx); /* cache_idx */
out_uint16_le(s, x);
out_uint16_le(s, y);
@ -506,7 +674,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
switch (bpp)
{
case 15:
//case 15: /* coverity: this is logically dead code */
case 16:
p16 = (tui16 *) data;
for (i = 0; i < 32; i++)
@ -547,9 +715,34 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
}
out_uint8a(s, mask, 128); /* mask */
out_uint8(s, 0); /* pad */
s_mark_end(s);
xrdp_rdp_send_data((struct xrdp_rdp *)(session->rdp), s,
RDP_DATA_PDU_POINTER);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
if ((session->client_info->pointer_flags & 1) == 0)
{
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_COLOR) != 0)
{
free_stream(s);
return 1;
}
}
else
{
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_POINTER) != 0)
{
free_stream(s);
return 1;
}
}
}
else
{
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_POINTER);
}
free_stream(s);
return 0;
}
@ -563,12 +756,41 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
DEBUG(("libxrdp_set_pointer sending cursor index"));
make_stream(s);
init_stream(s, 8192);
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
out_uint16_le(s, RDP_POINTER_CACHED);
out_uint16_le(s, 0); /* pad */
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
{
return 1;
}
}
else
{
LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
out_uint16_le(s, RDP_POINTER_CACHED);
out_uint16_le(s, 0); /* pad */
}
out_uint16_le(s, cache_idx); /* cache_idx */
s_mark_end(s);
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_POINTER);
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
{
if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
FASTPATH_UPDATETYPE_CACHED) != 0)
{
free_stream(s);
return 1;
}
}
else
{
xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
RDP_DATA_PDU_POINTER);
}
free_stream(s);
return 0;
}
@ -782,7 +1004,7 @@ libxrdp_reset(struct xrdp_session *session,
}
/* this should do the resizing */
if (xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp) != 0)
if (xrdp_caps_send_demand_active((struct xrdp_rdp *)session->rdp) != 0)
{
return 1;
}
@ -1079,3 +1301,91 @@ libxrdp_monitored_desktop(struct xrdp_session *session,
orders = (struct xrdp_orders *)(session->orders);
return xrdp_orders_send_monitored_desktop(orders, mdo, flags);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_codec_jpeg_compress(struct xrdp_session *session,
int format, char *inp_data,
int width, int height,
int stride, int x, int y,
int cx, int cy, int quality,
char *out_data, int *io_len)
{
struct xrdp_orders *orders;
void* jpeg_han;
orders = (struct xrdp_orders *)(session->orders);
jpeg_han = orders->jpeg_han;
return xrdp_codec_jpeg_compress(jpeg_han, format, inp_data,
width, height, stride, x, y,
cx, cy, quality, out_data, io_len);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_fastpath_send_surface(struct xrdp_session *session,
char* data_pad, int pad_bytes,
int data_bytes,
int destLeft, int destTop,
int destRight, int destBottom, int bpp,
int codecID, int width, int height)
{
struct stream ls;
struct stream *s;
struct xrdp_rdp *rdp;
int rv;
int sec_bytes;
int rdp_bytes;
int max_bytes;
int cmd_bytes;
LLOGLN(10, ("libxrdp_fastpath_init:"));
if ((session->client_info->use_fast_path & 1) == 0)
{
return 1;
}
max_bytes = session->client_info->max_fastpath_frag_bytes;
if (max_bytes < 32 * 1024)
{
max_bytes = 32 * 1024;
}
rdp = (struct xrdp_rdp *) (session->rdp);
rdp_bytes = xrdp_rdp_get_fastpath_bytes(rdp);
sec_bytes = xrdp_sec_get_fastpath_bytes(rdp->sec_layer);
cmd_bytes = 10 + 12;
if (data_bytes + rdp_bytes + sec_bytes + cmd_bytes > max_bytes)
{
return 1;
}
if (sec_bytes + rdp_bytes + cmd_bytes > pad_bytes)
{
return 1;
}
g_memset(&ls, 0, sizeof(ls));
s = &ls;
s->data = (data_pad + pad_bytes) - (rdp_bytes + sec_bytes + cmd_bytes);
s->sec_hdr = s->data;
s->rdp_hdr = s->sec_hdr + sec_bytes;
s->end = data_pad + pad_bytes + data_bytes;
s->p = s->data + (rdp_bytes + sec_bytes);
/* TS_SURFCMD_SET_SURF_BITS */
out_uint16_le(s, 0x0001); /* CMDTYPE_SET_SURFACE_BITS */
out_uint16_le(s, destLeft);
out_uint16_le(s, destTop);
out_uint16_le(s, destRight);
out_uint16_le(s, destBottom);
/* TS_ BITMAP_DATA_EX */
out_uint8(s, bpp);
out_uint8(s, 0);
out_uint8(s, 0);
out_uint8(s, codecID);
out_uint16_le(s, width);
out_uint16_le(s, height);
out_uint32_le(s, data_bytes);
/* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
{
return 1;
}
return 0;
}

@ -37,33 +37,46 @@
#include "file_loc.h"
#include "xrdp_client_info.h"
/* iso */
struct xrdp_iso
{
struct xrdp_mcs* mcs_layer; /* owner */
int requestedProtocol;
int selectedProtocol;
struct trans* trans;
struct xrdp_mcs *mcs_layer; /* owner */
int rdpNegData; /* bool */
int requestedProtocol;
int selectedProtocol;
int failureCode;
struct trans *trans;
};
/* used in mcs */
struct mcs_channel_item
{
char name[16];
int flags;
int chanid;
char name[16];
int flags;
int chanid;
};
/* mcs */
struct xrdp_mcs
{
struct xrdp_sec* sec_layer; /* owner */
struct xrdp_iso* iso_layer;
int userid;
int chanid;
struct stream* client_mcs_data;
struct stream* server_mcs_data;
struct list* channel_list;
struct xrdp_sec *sec_layer; /* owner */
struct xrdp_iso *iso_layer;
int userid;
int chanid;
struct stream *client_mcs_data;
struct stream *server_mcs_data;
struct list *channel_list;
};
/* fastpath */
struct xrdp_fastpath
{
struct xrdp_sec *sec_layer; /* owner */
struct trans *trans;
struct xrdp_session *session;
int numEvents;
int secFlags;
};
/* Encryption Methods */
@ -80,177 +93,181 @@ struct xrdp_mcs
#define CRYPT_LEVEL_HIGH 0x00000003
#define CRYPT_LEVEL_FIPS 0x00000004
/* sec */
struct xrdp_sec
{
struct xrdp_rdp* rdp_layer; /* owner */
struct xrdp_mcs* mcs_layer;
struct xrdp_channel* chan_layer;
char server_random[32];
char client_random[64];
char client_crypt_random[72];
struct stream client_mcs_data;
struct stream server_mcs_data;
int decrypt_use_count;
int encrypt_use_count;
char decrypt_key[16];
char encrypt_key[16];
char decrypt_update_key[16];
char encrypt_update_key[16];
int crypt_method;
int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */
int crypt_level;
char sign_key[16];
void* decrypt_rc4_info;
void* encrypt_rc4_info;
char pub_exp[4];
char pub_mod[64];
char pub_sig[64];
char pri_exp[64];
int channel_code;
int multimon;
char fips_encrypt_key[24];
char fips_decrypt_key[24];
char fips_sign_key[20];
void* encrypt_fips_info;
void* decrypt_fips_info;
void* sign_fips_info;
struct xrdp_rdp *rdp_layer; /* owner */
struct xrdp_mcs *mcs_layer;
struct xrdp_fastpath *fastpath_layer;
struct xrdp_channel *chan_layer;
char server_random[32];
char client_random[256];
char client_crypt_random[256 + 8]; /* 64 + 8, 256 + 8 */
struct stream client_mcs_data;
struct stream server_mcs_data;
int decrypt_use_count;
int encrypt_use_count;
char decrypt_key[16];
char encrypt_key[16];
char decrypt_update_key[16];
char encrypt_update_key[16];
int crypt_method;
int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */
int crypt_level;
char sign_key[16];
void *decrypt_rc4_info;
void *encrypt_rc4_info;
char pub_exp[4];
char pub_mod[256];
char pub_sig[64];
char pri_exp[256];
int rsa_key_bytes; /* 64 or 256 , 0 = no rdp security */
char fips_encrypt_key[24];
char fips_decrypt_key[24];
char fips_sign_key[20];
void *encrypt_fips_info;
void *decrypt_fips_info;
void *sign_fips_info;
};
/* channel */
struct xrdp_channel
{
struct xrdp_sec* sec_layer;
struct xrdp_mcs* mcs_layer;
struct xrdp_sec *sec_layer;
struct xrdp_mcs *mcs_layer;
};
/* rdp */
struct xrdp_rdp
{
struct xrdp_session* session;
struct xrdp_sec* sec_layer;
int share_id;
int mcs_channel;
struct xrdp_client_info client_info;
struct xrdp_mppc_enc* mppc_enc;
void* rfx_enc;
struct xrdp_session *session;
struct xrdp_sec *sec_layer;
int share_id;
int mcs_channel;
struct xrdp_client_info client_info;
struct xrdp_mppc_enc *mppc_enc;
void *rfx_enc;
};
/* state */
struct xrdp_orders_state
{
int last_order; /* last order sent */
int clip_left; /* RDP_ORDER_BOUNDS, RDP_ORDER_LASTBOUNDS */
int clip_top;
int clip_right;
int clip_bottom;
int rect_x; /* RDP_ORDER_RECT */
int rect_y;
int rect_cx;
int rect_cy;
int rect_color;
int scr_blt_x; /* RDP_ORDER_SCREENBLT */
int scr_blt_y;
int scr_blt_cx;
int scr_blt_cy;
int scr_blt_rop;
int scr_blt_srcx;
int scr_blt_srcy;
int pat_blt_x; /* RDP_ORDER_PATBLT */
int pat_blt_y;
int pat_blt_cx;
int pat_blt_cy;
int pat_blt_rop;
int pat_blt_bg_color;
int pat_blt_fg_color;
struct xrdp_brush pat_blt_brush;
int dest_blt_x; /* RDP_ORDER_DESTBLT */
int dest_blt_y;
int dest_blt_cx;
int dest_blt_cy;
int dest_blt_rop;
int line_mix_mode; /* RDP_ORDER_LINE */
int line_startx;
int line_starty;
int line_endx;
int line_endy;
int line_bg_color;
int line_rop;
struct xrdp_pen line_pen;
int mem_blt_color_table; /* RDP_ORDER_MEMBLT */
int mem_blt_cache_id;
int mem_blt_x;
int mem_blt_y;
int mem_blt_cx;
int mem_blt_cy;
int mem_blt_rop;
int mem_blt_srcx;
int mem_blt_srcy;
int mem_blt_cache_idx;
int text_font; /* RDP_ORDER_TEXT2 */
int text_flags;
int text_unknown;
int text_mixmode;
int text_fg_color;
int text_bg_color;
int text_clip_left;
int text_clip_top;
int text_clip_right;
int text_clip_bottom;
int text_box_left;
int text_box_top;
int text_box_right;
int text_box_bottom;
int text_x;
int text_y;
int text_len;
char* text_data;
int com_blt_srcidx; /* RDP_ORDER_COMPOSITE */ /* 2 */
int com_blt_srcformat; /* 2 */
int com_blt_srcwidth; /* 2 */
int com_blt_srcrepeat; /* 1 */
int com_blt_srctransform[10]; /* 40 */
int com_blt_mskflags; /* 1 */
int com_blt_mskidx; /* 2 */
int com_blt_mskformat; /* 2 */
int com_blt_mskwidth; /* 2 */
int com_blt_mskrepeat; /* 1 */
int com_blt_op; /* 1 */
int com_blt_srcx; /* 2 */
int com_blt_srcy; /* 2 */
int com_blt_mskx; /* 2 */
int com_blt_msky; /* 2 */
int com_blt_dstx; /* 2 */
int com_blt_dsty; /* 2 */
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
int last_order; /* last order sent */
int clip_left; /* RDP_ORDER_BOUNDS, RDP_ORDER_LASTBOUNDS */
int clip_top;
int clip_right;
int clip_bottom;
int rect_x; /* RDP_ORDER_RECT */
int rect_y;
int rect_cx;
int rect_cy;
int rect_color;
int scr_blt_x; /* RDP_ORDER_SCREENBLT */
int scr_blt_y;
int scr_blt_cx;
int scr_blt_cy;
int scr_blt_rop;
int scr_blt_srcx;
int scr_blt_srcy;
int pat_blt_x; /* RDP_ORDER_PATBLT */
int pat_blt_y;
int pat_blt_cx;
int pat_blt_cy;
int pat_blt_rop;
int pat_blt_bg_color;
int pat_blt_fg_color;
struct xrdp_brush pat_blt_brush;
int dest_blt_x; /* RDP_ORDER_DESTBLT */
int dest_blt_y;
int dest_blt_cx;
int dest_blt_cy;
int dest_blt_rop;
int line_mix_mode; /* RDP_ORDER_LINE */
int line_startx;
int line_starty;
int line_endx;
int line_endy;
int line_bg_color;
int line_rop;
struct xrdp_pen line_pen;
int mem_blt_color_table; /* RDP_ORDER_MEMBLT */
int mem_blt_cache_id;
int mem_blt_x;
int mem_blt_y;
int mem_blt_cx;
int mem_blt_cy;
int mem_blt_rop;
int mem_blt_srcx;
int mem_blt_srcy;
int mem_blt_cache_idx;
int text_font; /* RDP_ORDER_TEXT2 */
int text_flags;
int text_unknown;
int text_mixmode;
int text_fg_color;
int text_bg_color;
int text_clip_left;
int text_clip_top;
int text_clip_right;
int text_clip_bottom;
int text_box_left;
int text_box_top;
int text_box_right;
int text_box_bottom;
int text_x;
int text_y;
int text_len;
char *text_data;
int com_blt_srcidx; /* RDP_ORDER_COMPOSITE */ /* 2 */
int com_blt_srcformat; /* 2 */
int com_blt_srcwidth; /* 2 */
int com_blt_srcrepeat; /* 1 */
int com_blt_srctransform[10]; /* 40 */
int com_blt_mskflags; /* 1 */
int com_blt_mskidx; /* 2 */
int com_blt_mskformat; /* 2 */
int com_blt_mskwidth; /* 2 */
int com_blt_mskrepeat; /* 1 */
int com_blt_op; /* 1 */
int com_blt_srcx; /* 2 */
int com_blt_srcy; /* 2 */
int com_blt_mskx; /* 2 */
int com_blt_msky; /* 2 */
int com_blt_dstx; /* 2 */
int com_blt_dsty; /* 2 */
int com_blt_width; /* 2 */
int com_blt_height; /* 2 */
int com_blt_dstformat; /* 2 */
};
/* orders */
struct xrdp_orders
{
struct stream* out_s;
struct xrdp_rdp* rdp_layer;
struct xrdp_session* session;
struct xrdp_wm* wm;
char* order_count_ptr; /* pointer to count, set when sending */
int order_count;
int order_level; /* inc for every call to xrdp_orders_init */
struct xrdp_orders_state orders_state;
void* jpeg_han;
int rfx_min_pixel;
struct stream *out_s;
struct xrdp_rdp *rdp_layer;
struct xrdp_session *session;
struct xrdp_wm *wm;
char *order_count_ptr; /* pointer to count, set when sending */
int order_count;
int order_level; /* inc for every call to xrdp_orders_init */
struct xrdp_orders_state orders_state;
void *jpeg_han;
int rfx_min_pixel;
/* shared */
struct stream *s;
struct stream *temp_s;
};
#define PROTO_RDP_40 1
@ -258,19 +275,20 @@ struct xrdp_orders
struct xrdp_mppc_enc
{
int protocol_type; /* PROTO_RDP_40, PROTO_RDP_50 etc */
char *historyBuffer; /* contains uncompressed data */
char *outputBuffer; /* contains compressed data */
char *outputBufferPlus;
int historyOffset; /* next free slot in historyBuffer */
int buf_len; /* length of historyBuffer, protocol dependant */
int bytes_in_opb; /* compressed bytes available in outputBuffer */
int flags; /* PACKET_COMPRESSED, PACKET_AT_FRONT, PACKET_FLUSHED etc */
int flagsHold;
int first_pkt; /* this is the first pkt passing through enc */
tui16 *hash_table;
int protocol_type; /* PROTO_RDP_40, PROTO_RDP_50 etc */
char *historyBuffer; /* contains uncompressed data */
char *outputBuffer; /* contains compressed data */
char *outputBufferPlus;
int historyOffset; /* next free slot in historyBuffer */
int buf_len; /* length of historyBuffer, protocol dependant */
int bytes_in_opb; /* compressed bytes available in outputBuffer */
int flags; /* PACKET_COMPRESSED, PACKET_AT_FRONT, PACKET_FLUSHED etc */
int flagsHold;
int first_pkt; /* this is the first pkt passing through enc */
tui16 *hash_table;
};
int APP_CC
compress_rdp(struct xrdp_mppc_enc *enc, tui8 *srcData, int len);
struct xrdp_mppc_enc * APP_CC
@ -279,217 +297,225 @@ void APP_CC
mppc_enc_free(struct xrdp_mppc_enc *enc);
/* xrdp_tcp.c */
struct xrdp_tcp* APP_CC
xrdp_tcp_create(struct xrdp_iso* owner, struct trans* trans);
struct xrdp_tcp * APP_CC
xrdp_tcp_create(struct xrdp_iso *owner, struct trans *trans);
void APP_CC
xrdp_tcp_delete(struct xrdp_tcp* self);
xrdp_tcp_delete(struct xrdp_tcp *self);
int APP_CC
xrdp_tcp_init(struct xrdp_tcp* self, struct stream* s);
xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s);
int APP_CC
xrdp_tcp_recv(struct xrdp_tcp* self, struct stream* s, int len);
xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len);
int APP_CC
xrdp_tcp_send(struct xrdp_tcp* self, struct stream* s);
xrdp_tcp_send(struct xrdp_tcp *self, struct stream *s);
/* xrdp_iso.c */
struct xrdp_iso* APP_CC
xrdp_iso_create(struct xrdp_mcs* owner, struct trans* trans);
struct xrdp_iso * APP_CC
xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans);
void APP_CC
xrdp_iso_delete(struct xrdp_iso* self);
xrdp_iso_delete(struct xrdp_iso *self);
int APP_CC
xrdp_iso_init(struct xrdp_iso *self, struct stream *s);
int APP_CC
xrdp_iso_init(struct xrdp_iso* self, struct stream* s);
xrdp_iso_recv(struct xrdp_iso *self, struct stream *s);
int APP_CC
xrdp_iso_recv(struct xrdp_iso* self, struct stream* s);
xrdp_iso_send(struct xrdp_iso *self, struct stream *s);
int APP_CC
xrdp_iso_send(struct xrdp_iso* self, struct stream* s);
xrdp_iso_incoming(struct xrdp_iso *self);
int APP_CC
xrdp_iso_incoming(struct xrdp_iso* self);
xrdp_iso_detect_tpkt(struct xrdp_iso *self, struct stream *s);
/* xrdp_mcs.c */
struct xrdp_mcs* APP_CC
xrdp_mcs_create(struct xrdp_sec* owner, struct trans* trans,
struct stream* client_mcs_data,
struct stream* server_mcs_data);
struct xrdp_mcs * APP_CC
xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans,
struct stream *client_mcs_data,
struct stream *server_mcs_data);
void APP_CC
xrdp_mcs_delete(struct xrdp_mcs* self);
xrdp_mcs_delete(struct xrdp_mcs *self);
int APP_CC
xrdp_mcs_init(struct xrdp_mcs* self, struct stream* s);
xrdp_mcs_init(struct xrdp_mcs *self, struct stream *s);
int APP_CC
xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan);
xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan);
int APP_CC
xrdp_mcs_send(struct xrdp_mcs* self, struct stream* s, int chan);
xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan);
int APP_CC
xrdp_mcs_incoming(struct xrdp_mcs* self);
xrdp_mcs_incoming(struct xrdp_mcs *self);
int APP_CC
xrdp_mcs_disconnect(struct xrdp_mcs* self);
xrdp_mcs_disconnect(struct xrdp_mcs *self);
/* xrdp_sec.c */
struct xrdp_sec* APP_CC
xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level,
int channel_code, int multimon);
struct xrdp_sec *APP_CC
xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans);
void APP_CC
xrdp_sec_delete(struct xrdp_sec* self);
xrdp_sec_delete(struct xrdp_sec *self);
int APP_CC
xrdp_sec_init(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_get_fastpath_bytes(struct xrdp_sec *self);
int APP_CC
xrdp_sec_init_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_init(struct xrdp_sec* self, struct stream* s);
xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan);
xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s);
int APP_CC
xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int chan);
xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan);
int APP_CC
xrdp_sec_process_mcs_data(struct xrdp_sec* self);
xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan);
int APP_CC
xrdp_sec_out_mcs_data(struct xrdp_sec* self);
xrdp_sec_process_mcs_data(struct xrdp_sec *self);
int APP_CC
xrdp_sec_incoming(struct xrdp_sec* self);
xrdp_sec_incoming(struct xrdp_sec *self);
int APP_CC
xrdp_sec_disconnect(struct xrdp_sec* self);
xrdp_sec_disconnect(struct xrdp_sec *self);
/* xrdp_rdp.c */
struct xrdp_rdp* APP_CC
xrdp_rdp_create(struct xrdp_session* session, struct trans* trans);
struct xrdp_rdp * APP_CC
xrdp_rdp_create(struct xrdp_session *session, struct trans *trans);
void APP_CC
xrdp_rdp_delete(struct xrdp_rdp* self);
xrdp_rdp_delete(struct xrdp_rdp *self);
int APP_CC
xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s);
xrdp_rdp_init(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_init_data(struct xrdp_rdp* self, struct stream* s);
xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code);
xrdp_rdp_get_fastpath_bytes(struct xrdp_rdp *self);
int APP_CC
xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type);
xrdp_rdp_init_fastpath(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s,
int data_pdu_type);
xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code);
int APP_CC
xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self);
xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type);
int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp* self);
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type);
int APP_CC
xrdp_rdp_send_demand_active(struct xrdp_rdp* self);
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
int data_pdu_type);
int APP_CC
xrdp_rdp_send_monitorlayout(struct xrdp_rdp* self);
xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self);
int APP_CC
xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s);
xrdp_rdp_incoming(struct xrdp_rdp *self);
int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s);
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s);
int APP_CC
xrdp_rdp_disconnect(struct xrdp_rdp* self);
xrdp_rdp_disconnect(struct xrdp_rdp *self);
int APP_CC
xrdp_rdp_send_deactive(struct xrdp_rdp* self);
xrdp_rdp_send_deactive(struct xrdp_rdp *self);
/* xrdp_orders.c */
struct xrdp_orders* APP_CC
xrdp_orders_create(struct xrdp_session* session,
struct xrdp_rdp* rdp_layer);
struct xrdp_orders * APP_CC
xrdp_orders_create(struct xrdp_session *session,
struct xrdp_rdp *rdp_layer);
void APP_CC
xrdp_orders_delete(struct xrdp_orders* self);
xrdp_orders_delete(struct xrdp_orders *self);
int APP_CC
xrdp_orders_reset(struct xrdp_orders* self);
xrdp_orders_reset(struct xrdp_orders *self);
int APP_CC
xrdp_orders_init(struct xrdp_orders* self);
xrdp_orders_init(struct xrdp_orders *self);
int APP_CC
xrdp_orders_send(struct xrdp_orders* self);
xrdp_orders_send(struct xrdp_orders *self);
int APP_CC
xrdp_orders_force_send(struct xrdp_orders* self);
xrdp_orders_force_send(struct xrdp_orders *self);
int APP_CC
xrdp_orders_check(struct xrdp_orders* self, int max_size);
xrdp_orders_check(struct xrdp_orders *self, int max_size);
int APP_CC
xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy,
int color, struct xrdp_rect* rect);
xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy,
int color, struct xrdp_rect *rect);
int APP_CC
xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y,
xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y,
int cx, int cy, int srcx, int srcy,
int rop, struct xrdp_rect* rect);
int rop, struct xrdp_rect *rect);
int APP_CC
xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y,
xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y,
int cx, int cy, int rop, int bg_color,
int fg_color, struct xrdp_brush* brush,
struct xrdp_rect* rect);
int fg_color, struct xrdp_brush *brush,
struct xrdp_rect *rect);
int APP_CC
xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y,
xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y,
int cx, int cy, int rop,
struct xrdp_rect* rect);
struct xrdp_rect *rect);
int APP_CC
xrdp_orders_line(struct xrdp_orders* self, int mix_mode,
xrdp_orders_line(struct xrdp_orders *self, int mix_mode,
int startx, int starty,
int endx, int endy, int rop, int bg_color,
struct xrdp_pen* pen,
struct xrdp_rect* rect);
struct xrdp_pen *pen,
struct xrdp_rect *rect);
int APP_CC
xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id,
xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
int color_table, int x, int y, int cx, int cy,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int cache_idx, struct xrdp_rect *rect);
int APP_CC
xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx,
xrdp_orders_composite_blt(struct xrdp_orders *self, int srcidx,
int srcformat, int srcwidth,
int srcrepeat, int* srctransform, int mskflags,
int srcrepeat, int *srctransform, int mskflags,
int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat,
struct xrdp_rect* rect);
struct xrdp_rect *rect);
int APP_CC
xrdp_orders_text(struct xrdp_orders* self,
xrdp_orders_text(struct xrdp_orders *self,
int font, int flags, int mixmode,
int fg_color, int bg_color,
int clip_left, int clip_top,
int clip_right, int clip_bottom,
int box_left, int box_top,
int box_right, int box_bottom,
int x, int y, char* data, int data_len,
struct xrdp_rect* rect);
int x, int y, char *data, int data_len,
struct xrdp_rect *rect);
int APP_CC
xrdp_orders_send_palette(struct xrdp_orders* self, int* palette,
xrdp_orders_send_palette(struct xrdp_orders *self, int *palette,
int cache_id);
int APP_CC
xrdp_orders_send_raw_bitmap(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int APP_CC
xrdp_orders_send_bitmap(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
xrdp_orders_send_bitmap(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int APP_CC
xrdp_orders_send_font(struct xrdp_orders* self,
struct xrdp_font_char* font_char,
xrdp_orders_send_font(struct xrdp_orders *self,
struct xrdp_font_char *font_char,
int font_index, int char_index);
int APP_CC
xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int APP_CC
xrdp_orders_send_bitmap2(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
xrdp_orders_send_bitmap2(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx, int hints);
int APP_CC
xrdp_orders_send_bitmap3(struct xrdp_orders* self,
int width, int height, int bpp, char* data,
xrdp_orders_send_bitmap3(struct xrdp_orders *self,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx, int hints);
int APP_CC
xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height,
int bpp, int type, int size, char* data, int cache_id);
xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height,
int bpp, int type, int size, char *data, int cache_id);
int APP_CC
xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id,
xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id,
int width, int height,
struct list* del_list);
struct list *del_list);
int APP_CC
xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id);
xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id);
/* xrdp_bitmap_compress.c */
int APP_CC
xrdp_bitmap_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
xrdp_bitmap_compress(char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e);
int APP_CC
xrdp_bitmap32_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
int e);
xrdp_bitmap32_compress(char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e, int flags);
int APP_CC
xrdp_jpeg_compress(void *handle, char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e, int quality);
int APP_CC
@ -516,16 +542,35 @@ xrdp_jpeg_deinit(void *handle);
/* xrdp_channel.c */
struct xrdp_channel* APP_CC
xrdp_channel_create(struct xrdp_sec* owner, struct xrdp_mcs* mcs_layer);
xrdp_channel_create(struct xrdp_sec *owner, struct xrdp_mcs *mcs_layer);
void APP_CC
xrdp_channel_delete(struct xrdp_channel* self);
xrdp_channel_delete(struct xrdp_channel *self);
int APP_CC
xrdp_channel_init(struct xrdp_channel* self, struct stream* s);
xrdp_channel_init(struct xrdp_channel *self, struct stream *s);
int APP_CC
xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id,
xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
int total_data_len, int flags);
int APP_CC
xrdp_channel_process(struct xrdp_channel* self, struct stream* s,
xrdp_channel_process(struct xrdp_channel *self, struct stream *s,
int chanid);
/* xrdp_fastpath.c */
struct xrdp_fastpath *APP_CC
xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans);
void APP_CC
xrdp_fastpath_delete(struct xrdp_fastpath *self);
int APP_CC
xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s);
int APP_CC
xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s);
/* xrdp_caps.c */
int APP_CC
xrdp_caps_send_demand_active(struct xrdp_rdp *self);
int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,202 +27,220 @@
struct xrdp_brush
{
int x_orgin;
int y_orgin;
int style;
char pattern[8];
int x_orgin;
int y_orgin;
int style;
char pattern[8];
};
struct xrdp_pen
{
int style;
int width;
int color;
int style;
int width;
int color;
};
/* 2.2.2.2.1.2.5.1 Cache Glyph Data (TS_CACHE_GLYPH_DATA) */
struct xrdp_font_char
{
int offset; /* x */
int baseline; /* y */
int width; /* cx */
int height; /* cy */
int incby;
int bpp;
char* data;
int offset; /* x */
int baseline; /* y */
int width; /* cx */
int height; /* cy */
int incby;
int bpp;
char *data;
};
struct xrdp_rect
{
int left;
int top;
int right;
int bottom;
int left;
int top;
int right;
int bottom;
};
struct xrdp_session
{
long id;
struct trans* trans;
int (*callback)(long id, int msg, long param1, long param2, long param3,
long param4);
void* rdp;
void* orders;
struct xrdp_client_info* client_info;
int up_and_running;
int (*is_term)(void);
int in_process_data; /* inc / dec libxrdp_process_data calls */
tintptr id;
struct trans *trans;
int (*callback)(tintptr id, int msg, tintptr param1, tintptr param2,
tintptr param3, tintptr param4);
void *rdp;
void *orders;
struct xrdp_client_info *client_info;
int up_and_running;
int (*is_term)(void);
int in_process_data; /* inc / dec libxrdp_process_data calls */
};
struct xrdp_session* DEFAULT_CC
libxrdp_init(tbus id, struct trans* trans);
struct xrdp_session * DEFAULT_CC
libxrdp_init(tbus id, struct trans *trans);
int DEFAULT_CC
libxrdp_exit(struct xrdp_session* session);
libxrdp_exit(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_disconnect(struct xrdp_session* session);
libxrdp_disconnect(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_process_incomming(struct xrdp_session* session);
libxrdp_process_incomming(struct xrdp_session *session);
int EXPORT_CC
libxrdp_get_pdu_bytes(const char *aheader);
struct stream * APP_CC
libxrdp_force_read(struct trans *trans);
int DEFAULT_CC
libxrdp_process_data(struct xrdp_session* session, struct stream *s);
libxrdp_process_data(struct xrdp_session *session, struct stream *s);
int DEFAULT_CC
libxrdp_send_palette(struct xrdp_session* session, int* palette);
libxrdp_send_palette(struct xrdp_session *session, int *palette);
int DEFAULT_CC
libxrdp_send_bell(struct xrdp_session* session);
libxrdp_send_bell(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_send_bitmap(struct xrdp_session* session, int width, int height,
int bpp, char* data, int x, int y, int cx, int cy);
libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
int bpp, char *data, int x, int y, int cx, int cy);
int DEFAULT_CC
libxrdp_send_pointer(struct xrdp_session* session, int cache_idx,
char* data, char* mask, int x, int y, int bpp);
libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
char *data, char *mask, int x, int y, int bpp);
int DEFAULT_CC
libxrdp_set_pointer(struct xrdp_session* session, int cache_idx);
libxrdp_set_pointer(struct xrdp_session *session, int cache_idx);
int DEFAULT_CC
libxrdp_orders_init(struct xrdp_session* session);
libxrdp_orders_init(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_orders_send(struct xrdp_session* session);
libxrdp_orders_send(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_orders_force_send(struct xrdp_session* session);
libxrdp_orders_force_send(struct xrdp_session *session);
int DEFAULT_CC
libxrdp_orders_rect(struct xrdp_session* session, int x, int y,
int cx, int cy, int color, struct xrdp_rect* rect);
libxrdp_orders_rect(struct xrdp_session *session, int x, int y,
int cx, int cy, int color, struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_screen_blt(struct xrdp_session* session, int x, int y,
libxrdp_orders_screen_blt(struct xrdp_session *session, int x, int y,
int cx, int cy, int srcx, int srcy,
int rop, struct xrdp_rect* rect);
int rop, struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_pat_blt(struct xrdp_session* session, int x, int y,
libxrdp_orders_pat_blt(struct xrdp_session *session, int x, int y,
int cx, int cy, int rop, int bg_color,
int fg_color, struct xrdp_brush* brush,
struct xrdp_rect* rect);
int fg_color, struct xrdp_brush *brush,
struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_dest_blt(struct xrdp_session* session, int x, int y,
libxrdp_orders_dest_blt(struct xrdp_session *session, int x, int y,
int cx, int cy, int rop,
struct xrdp_rect* rect);
struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_line(struct xrdp_session* session, int mix_mode,
libxrdp_orders_line(struct xrdp_session *session, int mix_mode,
int startx, int starty,
int endx, int endy, int rop, int bg_color,
struct xrdp_pen* pen,
struct xrdp_rect* rect);
struct xrdp_pen *pen,
struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id,
libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
int color_table, int x, int y, int cx, int cy,
int rop, int srcx, int srcy,
int cache_idx, struct xrdp_rect* rect);
int cache_idx, struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
libxrdp_orders_composite_blt(struct xrdp_session *session, int srcidx,
int srcformat, int srcwidth, int srcrepeat,
int* srctransform, int mskflags,
int *srctransform, int mskflags,
int mskidx, int mskformat, int mskwidth,
int mskrepeat, int op, int srcx, int srcy,
int mskx, int msky, int dstx, int dsty,
int width, int height, int dstformat,
struct xrdp_rect* rect);
struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_text(struct xrdp_session* session,
libxrdp_orders_text(struct xrdp_session *session,
int font, int flags, int mixmode,
int fg_color, int bg_color,
int clip_left, int clip_top,
int clip_right, int clip_bottom,
int box_left, int box_top,
int box_right, int box_bottom,
int x, int y, char* data, int data_len,
struct xrdp_rect* rect);
int x, int y, char *data, int data_len,
struct xrdp_rect *rect);
int DEFAULT_CC
libxrdp_orders_send_palette(struct xrdp_session* session, int* palette,
libxrdp_orders_send_palette(struct xrdp_session *session, int *palette,
int cache_id);
int DEFAULT_CC
libxrdp_orders_send_raw_bitmap(struct xrdp_session* session,
int width, int height, int bpp, char* data,
libxrdp_orders_send_raw_bitmap(struct xrdp_session *session,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int DEFAULT_CC
libxrdp_orders_send_bitmap(struct xrdp_session* session,
int width, int height, int bpp, char* data,
libxrdp_orders_send_bitmap(struct xrdp_session *session,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int DEFAULT_CC
libxrdp_orders_send_font(struct xrdp_session* session,
struct xrdp_font_char* font_char,
libxrdp_orders_send_font(struct xrdp_session *session,
struct xrdp_font_char *font_char,
int font_index, int char_index);
int DEFAULT_CC
libxrdp_reset(struct xrdp_session* session,
libxrdp_reset(struct xrdp_session *session,
int width, int height, int bpp);
int DEFAULT_CC
libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session,
int width, int height, int bpp, char* data,
libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx);
int DEFAULT_CC
libxrdp_orders_send_bitmap2(struct xrdp_session* session,
int width, int height, int bpp, char* data,
libxrdp_orders_send_bitmap2(struct xrdp_session *session,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx, int hints);
int DEFAULT_CC
libxrdp_orders_send_bitmap3(struct xrdp_session* session,
int width, int height, int bpp, char* data,
libxrdp_orders_send_bitmap3(struct xrdp_session *session,
int width, int height, int bpp, char *data,
int cache_id, int cache_idx, int hints);
int DEFAULT_CC
libxrdp_query_channel(struct xrdp_session* session, int index,
char* channel_name, int* channel_flags);
libxrdp_query_channel(struct xrdp_session *session, int index,
char *channel_name, int *channel_flags);
int DEFAULT_CC
libxrdp_get_channel_id(struct xrdp_session* session, char* name);
libxrdp_get_channel_id(struct xrdp_session *session, char *name);
int DEFAULT_CC
libxrdp_send_to_channel(struct xrdp_session* session, int channel_id,
char* data, int data_len,
libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
char *data, int data_len,
int total_data_len, int flags);
int DEFAULT_CC
libxrdp_orders_send_brush(struct xrdp_session* session,
libxrdp_orders_send_brush(struct xrdp_session *session,
int width, int height, int bpp, int type,
int size, char* data, int cache_id);
int size, char *data, int cache_id);
int DEFAULT_CC
libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id,
libxrdp_orders_send_create_os_surface(struct xrdp_session *session, int id,
int width, int height,
struct list* del_list);
struct list *del_list);
int DEFAULT_CC
libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id);
libxrdp_orders_send_switch_os_surface(struct xrdp_session *session, int id);
int DEFAULT_CC
libxrdp_window_new_update(struct xrdp_session* session, int window_id,
struct rail_window_state_order* window_state,
libxrdp_window_new_update(struct xrdp_session *session, int window_id,
struct rail_window_state_order *window_state,
int flags);
int DEFAULT_CC
libxrdp_window_delete(struct xrdp_session* session, int window_id);
libxrdp_window_delete(struct xrdp_session *session, int window_id);
int DEFAULT_CC
libxrdp_window_icon(struct xrdp_session* session, int window_id,
libxrdp_window_icon(struct xrdp_session *session, int window_id,
int cache_entry, int cache_id,
struct rail_icon_info* icon_info, int flags);
struct rail_icon_info *icon_info, int flags);
int DEFAULT_CC
libxrdp_window_cached_icon(struct xrdp_session* session, int window_id,
libxrdp_window_cached_icon(struct xrdp_session *session, int window_id,
int cache_entry, int cache_id,
int flags);
int DEFAULT_CC
libxrdp_notify_new_update(struct xrdp_session* session,
libxrdp_notify_new_update(struct xrdp_session *session,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
struct rail_notify_state_order *notify_state,
int flags);
int DEFAULT_CC
libxrdp_notify_delete(struct xrdp_session* session,
libxrdp_notify_delete(struct xrdp_session *session,
int window_id, int notify_id);
int DEFAULT_CC
libxrdp_monitored_desktop(struct xrdp_session* session,
struct rail_monitored_desktop_order* mdo,
libxrdp_monitored_desktop(struct xrdp_session *session,
struct rail_monitored_desktop_order *mdo,
int flags);
int DEFAULT_CC
libxrdp_codec_jpeg_compress(struct xrdp_session *session,
int format, char *inp_data,
int width, int height,
int stride, int x, int y,
int cx, int cy, int quality,
char *out_data, int *io_len);
int DEFAULT_CC
libxrdp_fastpath_send_surface(struct xrdp_session *session,
char *data_pad, int pad_bytes,
int data_bytes,
int destLeft, int dst_Top,
int destRight, int destBottom, int bpp,
int codecID, int width, int height);
#endif

@ -19,14 +19,518 @@
* 32 bpp compression
*/
/*
RDP 6.0 Bitmap Compression
http://msdn.microsoft.com/en-us/library/cc241877.aspx
*/
#include "libxrdp.h"
#define FLAGS_RLE 0x10
#define FLAGS_NOALPHA 0x20
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LLOG_LEVEL) { g_writeln _args ; } } while (0)
#define LHEXDUMP(_level, _args) \
do { if (_level < LLOG_LEVEL) { g_hexdump _args ; } } while (0)
/*****************************************************************************/
/* split RGB */
static int APP_CC
fsplit3(char *in_data, int start_line, int width, int e,
char *r_data, char *g_data, char *b_data)
{
#if defined(L_ENDIAN)
int rp;
int gp;
int bp;
#endif
int index;
int out_index;
int pixel;
int cy;
int *ptr32;
cy = 0;
out_index = 0;
while (start_line >= 0)
{
ptr32 = (int *) (in_data + start_line * width * 4);
index = 0;
#if defined(L_ENDIAN)
while (index + 4 <= width)
{
pixel = *ptr32;
ptr32++;
rp = (pixel >> 16) & 0x000000ff;
gp = (pixel >> 8) & 0x000000ff;
bp = (pixel >> 0) & 0x000000ff;
pixel = *ptr32;
ptr32++;
rp |= (pixel >> 8) & 0x0000ff00;
gp |= (pixel << 0) & 0x0000ff00;
bp |= (pixel << 8) & 0x0000ff00;
pixel = *ptr32;
ptr32++;
rp |= (pixel >> 0) & 0x00ff0000;
gp |= (pixel << 8) & 0x00ff0000;
bp |= (pixel << 16) & 0x00ff0000;
pixel = *ptr32;
ptr32++;
rp |= (pixel << 8) & 0xff000000;
gp |= (pixel << 16) & 0xff000000;
bp |= (pixel << 24) & 0xff000000;
*((int*)(r_data + out_index)) = rp;
*((int*)(g_data + out_index)) = gp;
*((int*)(b_data + out_index)) = bp;
out_index += 4;
index += 4;
}
#endif
while (index < width)
{
pixel = *ptr32;
ptr32++;
r_data[out_index] = pixel >> 16;
g_data[out_index] = pixel >> 8;
b_data[out_index] = pixel >> 0;
out_index++;
index++;
}
for (index = 0; index < e; index++)
{
r_data[out_index] = r_data[out_index - 1];
g_data[out_index] = g_data[out_index - 1];
b_data[out_index] = b_data[out_index - 1];
out_index++;
}
start_line--;
cy++;
if (out_index > 64 * 64)
{
break;
}
}
return cy;
}
/*****************************************************************************/
/* split ARGB */
static int APP_CC
fsplit4(char *in_data, int start_line, int width, int e,
char *a_data, char *r_data, char *g_data, char *b_data)
{
#if defined(L_ENDIAN)
int ap;
int rp;
int gp;
int bp;
#endif
int index;
int out_index;
int pixel;
int cy;
int *ptr32;
cy = 0;
out_index = 0;
while (start_line >= 0)
{
ptr32 = (int *) (in_data + start_line * width * 4);
index = 0;
#if defined(L_ENDIAN)
while (index + 4 <= width)
{
pixel = *ptr32;
ptr32++;
ap = (pixel >> 24) & 0x000000ff;
rp = (pixel >> 16) & 0x000000ff;
gp = (pixel >> 8) & 0x000000ff;
bp = (pixel >> 0) & 0x000000ff;
pixel = *ptr32;
ptr32++;
ap |= (pixel >> 16) & 0x0000ff00;
rp |= (pixel >> 8) & 0x0000ff00;
gp |= (pixel << 0) & 0x0000ff00;
bp |= (pixel << 8) & 0x0000ff00;
pixel = *ptr32;
ptr32++;
ap |= (pixel >> 8) & 0x00ff0000;
rp |= (pixel >> 0) & 0x00ff0000;
gp |= (pixel << 8) & 0x00ff0000;
bp |= (pixel << 16) & 0x00ff0000;
pixel = *ptr32;
ptr32++;
ap |= (pixel << 0) & 0xff000000;
rp |= (pixel << 8) & 0xff000000;
gp |= (pixel << 16) & 0xff000000;
bp |= (pixel << 24) & 0xff000000;
*((int*)(a_data + out_index)) = ap;
*((int*)(r_data + out_index)) = rp;
*((int*)(g_data + out_index)) = gp;
*((int*)(b_data + out_index)) = bp;
out_index += 4;
index += 4;
}
#endif
while (index < width)
{
pixel = *ptr32;
ptr32++;
a_data[out_index] = pixel >> 24;
r_data[out_index] = pixel >> 16;
g_data[out_index] = pixel >> 8;
b_data[out_index] = pixel >> 0;
out_index++;
index++;
}
for (index = 0; index < e; index++)
{
a_data[out_index] = a_data[out_index - 1];
r_data[out_index] = r_data[out_index - 1];
g_data[out_index] = g_data[out_index - 1];
b_data[out_index] = b_data[out_index - 1];
out_index++;
}
start_line--;
cy++;
if (out_index > 64 * 64)
{
break;
}
}
return cy;
}
/*****************************************************************************/
#define DELTA_ONE \
do { \
delta = src8[cx] - src8[0]; \
is_neg = (delta >> 7) & 1; \
dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
src8++; \
dst8++; \
} while (0)
/*****************************************************************************/
static int APP_CC
fdelta(char *in_plane, char *out_plane, int cx, int cy)
{
char delta;
char is_neg;
char *src8;
char *dst8;
char *src8_end;
g_memcpy(out_plane, in_plane, cx);
src8 = in_plane;
dst8 = out_plane;
src8_end = src8 + (cx * cy - cx);
while (src8 + 8 <= src8_end)
{
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
DELTA_ONE;
}
while (src8 < src8_end)
{
DELTA_ONE;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
fout(int collen, int replen, char *colptr, struct stream *s)
{
int code;
int lcollen;
int lreplen;
int cont;
LLOGLN(10, ("fout: collen %d replen %d", collen, replen));
cont = collen > 13;
while (cont)
{
lcollen = collen;
if (lcollen > 15)
{
lcollen = 15;
}
code = lcollen << 4;
out_uint8(s, code);
out_uint8a(s, colptr, lcollen);
colptr += lcollen;
collen -= lcollen;
cont = collen > 13;
}
cont = (collen > 0) || (replen > 0);
while (cont)
{
lreplen = replen;
if ((collen == 0) && (lreplen > 15))
{
/* big run */
if (lreplen > 47)
{
lreplen = 47;
}
LLOGLN(10, ("fout: big run lreplen %d", lreplen));
replen -= lreplen;
code = ((lreplen & 0xF) << 4) | ((lreplen & 0xF0) >> 4);
out_uint8(s, code);
colptr += lreplen;
}
else
{
if (lreplen > 15)
{
lreplen = 15;
}
replen -= lreplen;
if (lreplen < 3)
{
collen += lreplen;
lreplen = 0;
}
code = (collen << 4) | lreplen;
out_uint8(s, code);
out_uint8a(s, colptr, collen);
colptr += collen + lreplen;
collen = 0;
}
cont = replen > 0;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
fpack(char *plane, int cx, int cy, struct stream *s)
{
char *ptr8;
char *colptr;
char *lend;
char *holdp;
int jndex;
int collen;
int replen;
LLOGLN(10, ("fpack:"));
holdp = s->p;
for (jndex = 0; jndex < cy; jndex++)
{
LLOGLN(10, ("line start line %d cx %d cy %d", jndex, cx, cy));
ptr8 = plane + jndex * cx;
LHEXDUMP(10, (ptr8, cx));
lend = ptr8 + (cx - 1);
colptr = ptr8;
if (colptr[0] == 0)
{
collen = 0;
replen = 1;
}
else
{
collen = 1;
replen = 0;
}
while (ptr8 < lend)
{
if (ptr8[0] == ptr8[1])
{
replen++;
}
else
{
if (replen > 0)
{
if (replen < 3)
{
collen += replen + 1;
replen = 0;
}
else
{
fout(collen, replen, colptr, s);
colptr = ptr8 + 1;
replen = 0;
collen = 1;
}
}
else
{
collen++;
}
}
ptr8++;
}
/* end of line */
fout(collen, replen, colptr, s);
}
return (int) (s->p - holdp);
}
/*****************************************************************************/
static int APP_CC
foutraw3(struct stream *s, int bytes, int header,
char *r_data, char *g_data, char *b_data)
{
out_uint8(s, header);
out_uint8a(s, r_data, bytes);
out_uint8a(s, g_data, bytes);
out_uint8a(s, b_data, bytes);
/* pad if no RLE */
out_uint8(s, 0x00);
return 0;
}
/*****************************************************************************/
static int APP_CC
foutraw4(struct stream *s, int bytes, int header,
char *a_data, char *r_data, char *g_data, char *b_data)
{
out_uint8(s, header);
out_uint8a(s, a_data, bytes);
out_uint8a(s, r_data, bytes);
out_uint8a(s, g_data, bytes);
out_uint8a(s, b_data, bytes);
/* pad if no RLE */
out_uint8(s, 0x00);
return 0;
}
/*****************************************************************************/
/* returns the number of lines compressed */
int APP_CC
xrdp_bitmap32_compress(char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e)
int e, int flags)
{
return 0;
char *a_data;
char *r_data;
char *g_data;
char *b_data;
char *sa_data;
char *sr_data;
char *sg_data;
char *sb_data;
int a_bytes;
int r_bytes;
int g_bytes;
int b_bytes;
int cx;
int cy;
int max_bytes;
int total_bytes;
int header;
LLOGLN(10, ("xrdp_bitmap32_compress:"));
max_bytes = 4 * 1024;
/* need max 8, 4K planes for work */
if (max_bytes * 8 > temp_s->size)
{
return 0;
}
header = flags & 0xFF;
cx = width + e;
sa_data = temp_s->data;
sr_data = sa_data + max_bytes;
sg_data = sr_data + max_bytes;
sb_data = sg_data + max_bytes;
a_data = sb_data + max_bytes;
r_data = a_data + max_bytes;
g_data = r_data + max_bytes;
b_data = g_data + max_bytes;
if (header & FLAGS_NOALPHA)
{
cy = fsplit3(in_data, start_line, width, e,
sr_data, sg_data, sb_data);
if (header & FLAGS_RLE)
{
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
out_uint8(s, header);
r_bytes = fpack(r_data, cx, cy, s);
g_bytes = fpack(g_data, cx, cy, s);
b_bytes = fpack(b_data, cx, cy, s);
total_bytes = r_bytes + g_bytes + b_bytes;
if (1 + total_bytes > byte_limit)
{
/* failed */
LLOGLN(0, ("xrdp_bitmap32_compress: too big, rgb "
"bytes %d %d %d total_bytes %d cx %d cy %d "
"byte_limit %d", r_bytes, g_bytes, b_bytes,
total_bytes, cx, cy, byte_limit));
return 0;
}
max_bytes = cx * cy * 3;
if (total_bytes > max_bytes)
{
/* raw is better */
LLOGLN(10, ("xrdp_bitmap32_compress: too big, rgb "
"bytes %d %d %d total_bytes %d cx %d cy %d "
"max_bytes %d", r_bytes, g_bytes, b_bytes,
total_bytes, cx, cy, max_bytes));
init_stream(s, 0);
foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
}
}
else
{
foutraw3(s, cx * cy, FLAGS_NOALPHA, sr_data, sg_data, sb_data);
}
}
else
{
cy = fsplit4(in_data, start_line, width, e,
sa_data, sr_data, sg_data, sb_data);
if (header & FLAGS_RLE)
{
fdelta(sa_data, a_data, cx, cy);
fdelta(sr_data, r_data, cx, cy);
fdelta(sg_data, g_data, cx, cy);
fdelta(sb_data, b_data, cx, cy);
out_uint8(s, header);
a_bytes = fpack(a_data, cx, cy, s);
r_bytes = fpack(r_data, cx, cy, s);
g_bytes = fpack(g_data, cx, cy, s);
b_bytes = fpack(b_data, cx, cy, s);
max_bytes = cx * cy * 4;
total_bytes = a_bytes + r_bytes + g_bytes + b_bytes;
if (1 + total_bytes > byte_limit)
{
/* failed */
LLOGLN(0, ("xrdp_bitmap32_compress: too big, argb "
"bytes %d %d %d %d total_bytes %d cx %d cy %d "
"byte_limit %d", a_bytes, r_bytes, g_bytes, b_bytes,
total_bytes, cx, cy, byte_limit));
return 0;
}
if (total_bytes > max_bytes)
{
/* raw is better */
LLOGLN(10, ("xrdp_bitmap32_compress: too big, argb "
"bytes %d %d %d %d total_bytes %d cx %d cy %d "
"max_bytes %d", a_bytes, r_bytes, g_bytes, b_bytes,
total_bytes, cx, cy, max_bytes));
init_stream(s, 0);
foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
}
}
else
{
foutraw4(s, cx * cy, 0, sa_data, sr_data, sg_data, sb_data);
}
}
return cy;
}

@ -0,0 +1,916 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2014
* Copyright (C) Idan Freiberg 2004-2014
*
* Licensed 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.
*
* RDP Capability Sets
*/
#include "libxrdp.h"
/*****************************************************************************/
static int APP_CC
xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
{
struct stream *s;
int i;
make_stream(s);
init_stream(s, 8192);
if (xrdp_rdp_init_data(self, s) != 0)
{
free_stream(s);
return 1;
}
out_uint32_le(s, self->client_info.monitorCount); /* monitorCount (4 bytes) */
/* TODO: validate for allowed monitors in terminal server (maybe by config?) */
for (i = 0; i < self->client_info.monitorCount; i++)
{
out_uint32_le(s, self->client_info.minfo[i].left);
out_uint32_le(s, self->client_info.minfo[i].top);
out_uint32_le(s, self->client_info.minfo[i].right);
out_uint32_le(s, self->client_info.minfo[i].bottom);
out_uint32_le(s, self->client_info.minfo[i].is_primary);
}
s_mark_end(s);
if (xrdp_rdp_send_data(self, s, 0x37) != 0)
{
free_stream(s);
return 1;
}
free_stream(s);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
int len)
{
int extraFlags;
int client_does_fastpath_output;
if (len < 10 + 2)
{
g_writeln("xrdp_caps_process_general: error");
return 1;
}
in_uint8s(s, 10);
in_uint16_le(s, extraFlags);
/* use_compact_packets is pretty much 'use rdp5' */
self->client_info.use_compact_packets = (extraFlags != 0);
/* op2 is a boolean to use compact bitmap headers in bitmap cache */
/* set it to same as 'use rdp5' boolean */
self->client_info.op2 = self->client_info.use_compact_packets;
/* FASTPATH_OUTPUT_SUPPORTED 0x0001 */
client_does_fastpath_output = extraFlags & FASTPATH_OUTPUT_SUPPORTED;
if ((self->client_info.use_fast_path & 1) && !client_does_fastpath_output)
{
/* server supports fast path output and client does not, turn it off */
self->client_info.use_fast_path &= ~1;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
int len)
{
int i;
char order_caps[32];
int ex_flags;
int cap_flags;
DEBUG(("order capabilities"));
if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
{
g_writeln("xrdp_caps_process_order: error");
return 1;
}
in_uint8s(s, 20); /* Terminal desc, pad */
in_uint8s(s, 2); /* Cache X granularity */
in_uint8s(s, 2); /* Cache Y granularity */
in_uint8s(s, 2); /* Pad */
in_uint8s(s, 2); /* Max order level */
in_uint8s(s, 2); /* Number of fonts */
in_uint16_le(s, cap_flags); /* Capability flags */
in_uint8a(s, order_caps, 32); /* Orders supported */
g_memcpy(self->client_info.orders, order_caps, 32);
DEBUG(("dest blt-0 %d", order_caps[0]));
DEBUG(("pat blt-1 %d", order_caps[1]));
DEBUG(("screen blt-2 %d", order_caps[2]));
DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13]));
DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14]));
DEBUG(("line-8 %d", order_caps[8]));
DEBUG(("line-9 %d", order_caps[9]));
DEBUG(("rect-10 %d", order_caps[10]));
DEBUG(("desksave-11 %d", order_caps[11]));
DEBUG(("polygon-20 %d", order_caps[20]));
DEBUG(("polygon2-21 %d", order_caps[21]));
DEBUG(("polyline-22 %d", order_caps[22]));
DEBUG(("ellipse-25 %d", order_caps[25]));
DEBUG(("ellipse2-26 %d", order_caps[26]));
DEBUG(("text2-27 %d", order_caps[27]));
DEBUG(("order_caps dump"));
#if defined(XRDP_DEBUG)
g_hexdump(order_caps, 32);
#endif
in_uint8s(s, 2); /* Text capability flags */
/* read extended order support flags */
in_uint16_le(s, ex_flags); /* Ex flags */
if (cap_flags & 0x80) /* ORDER_FLAGS_EXTRA_SUPPORT */
{
self->client_info.order_flags_ex = ex_flags;
if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT)
{
g_writeln("xrdp_caps_process_order: bitmap cache v3 supported");
self->client_info.bitmap_cache_version |= 4;
}
}
in_uint8s(s, 4); /* Pad */
in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */
self->client_info.desktop_cache = i;
DEBUG(("desktop cache size %d", i));
in_uint8s(s, 4); /* Unknown */
in_uint8s(s, 4); /* Unknown */
return 0;
}
/*****************************************************************************/
/* get the bitmap cache size */
static int APP_CC
xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s,
int len)
{
int i;
if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
{
g_writeln("xrdp_caps_process_bmpcache: error");
return 1;
}
self->client_info.bitmap_cache_version |= 1;
in_uint8s(s, 24);
/* cache 1 */
in_uint16_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache1_entries = i;
in_uint16_le(s, self->client_info.cache1_size);
/* cache 2 */
in_uint16_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache2_entries = i;
in_uint16_le(s, self->client_info.cache2_size);
/* caceh 3 */
in_uint16_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache3_entries = i;
in_uint16_le(s, self->client_info.cache3_size);
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
self->client_info.cache1_size));
DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
self->client_info.cache2_size));
DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
self->client_info.cache3_size));
return 0;
}
/*****************************************************************************/
/* get the bitmap cache size */
static int APP_CC
xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s,
int len)
{
int Bpp = 0;
int i = 0;
if (len < 2 + 2 + 4 + 4 + 4)
{
g_writeln("xrdp_caps_process_bmpcache2: error");
return 1;
}
self->client_info.bitmap_cache_version |= 2;
Bpp = (self->client_info.bpp + 7) / 8;
in_uint16_le(s, i); /* cache flags */
self->client_info.bitmap_cache_persist_enable = i;
in_uint8s(s, 2); /* number of caches in set, 3 */
in_uint32_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache1_entries = i;
self->client_info.cache1_size = 256 * Bpp;
in_uint32_le(s, i);
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache2_entries = i;
self->client_info.cache2_size = 1024 * Bpp;
in_uint32_le(s, i);
i = i & 0x7fffffff;
i = MIN(i, XRDP_MAX_BITMAP_CACHE_IDX);
i = MAX(i, 0);
self->client_info.cache3_entries = i;
self->client_info.cache3_size = 4096 * Bpp;
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
self->client_info.cache1_size));
DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
self->client_info.cache2_size));
DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
self->client_info.cache3_size));
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
int len)
{
int codec_id;
if (len < 1)
{
g_writeln("xrdp_caps_process_cache_v3_codec_id: error");
return 1;
}
in_uint8(s, codec_id);
g_writeln("xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d",
codec_id);
self->client_info.v3_codec_id = codec_id;
return 0;
}
/*****************************************************************************/
/* get the number of client cursor cache */
static int APP_CC
xrdp_caps_process_pointer(struct xrdp_rdp *self, struct stream *s,
int len)
{
int i;
int colorPointerFlag;
int no_new_cursor;
if (len < 2 + 2 + 2)
{
g_writeln("xrdp_caps_process_pointer: error");
return 1;
}
no_new_cursor = self->client_info.pointer_flags & 2;
in_uint16_le(s, colorPointerFlag);
self->client_info.pointer_flags = colorPointerFlag;
in_uint16_le(s, i);
i = MIN(i, 32);
self->client_info.pointer_cache_entries = i;
if (colorPointerFlag & 1)
{
g_writeln("xrdp_caps_process_pointer: client supports "
"new(color) cursor");
in_uint16_le(s, i);
i = MIN(i, 32);
self->client_info.pointer_cache_entries = i;
}
else
{
g_writeln("xrdp_caps_process_pointer: client does not support "
"new(color) cursor");
}
if (no_new_cursor)
{
g_writeln("xrdp_caps_process_pointer: new(color) cursor is "
"disabled by config");
self->client_info.pointer_flags = 0;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_input(struct xrdp_rdp *self, struct stream *s,
int len)
{
int inputFlags;
int client_does_fastpath_input;
in_uint16_le(s, inputFlags);
client_does_fastpath_input = (inputFlags & INPUT_FLAG_FASTPATH_INPUT) ||
(inputFlags & INPUT_FLAG_FASTPATH_INPUT2);
if ((self->client_info.use_fast_path & 2) && !client_does_fastpath_input)
{
self->client_info.use_fast_path &= ~2;
}
return 0;
}
/*****************************************************************************/
/* get the type of client brush cache */
int APP_CC
xrdp_caps_process_brushcache(struct xrdp_rdp *self, struct stream *s,
int len)
{
int code;
if (len < 4)
{
g_writeln("xrdp_caps_process_brushcache: error");
return 1;
}
in_uint32_le(s, code);
self->client_info.brush_cache_code = code;
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
int len)
{
int i32;
if (len < 4 + 2 + 2)
{
g_writeln("xrdp_caps_process_offscreen_bmpcache: error");
return 1;
}
in_uint32_le(s, i32);
self->client_info.offscreen_support_level = i32;
in_uint16_le(s, i32);
self->client_info.offscreen_cache_size = i32 * 1024;
in_uint16_le(s, i32);
self->client_info.offscreen_cache_entries = i32;
g_writeln("xrdp_process_offscreen_bmpcache: support level %d "
"cache size %d MB cache entries %d",
self->client_info.offscreen_support_level,
self->client_info.offscreen_cache_size,
self->client_info.offscreen_cache_entries);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
if (len < 4)
{
g_writeln("xrdp_caps_process_rail: error");
return 1;
}
in_uint32_le(s, i32);
self->client_info.rail_support_level = i32;
g_writeln("xrdp_process_capset_rail: rail_support_level %d",
self->client_info.rail_support_level);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len)
{
int i32;
if (len < 4 + 1 + 2)
{
g_writeln("xrdp_caps_process_window: error");
return 1;
}
in_uint32_le(s, i32);
self->client_info.wnd_support_level = i32;
in_uint8(s, i32);
self->client_info.wnd_num_icon_caches = i32;
in_uint16_le(s, i32);
self->client_info.wnd_num_icon_cache_entries = i32;
g_writeln("xrdp_process_capset_window wnd_support_level %d "
"wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
self->client_info.wnd_support_level,
self->client_info.wnd_num_icon_caches,
self->client_info.wnd_num_icon_cache_entries);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
{
int codec_id;
int codec_count;
int index;
int codec_properties_length;
int i1;
char *codec_guid;
char *next_guid;
if (len < 1)
{
g_writeln("xrdp_caps_process_codecs: error");
return 1;
}
in_uint8(s, codec_count);
len--;
for (index = 0; index < codec_count; index++)
{
codec_guid = s->p;
if (len < 16 + 1 + 2)
{
g_writeln("xrdp_caps_process_codecs: error");
return 1;
}
in_uint8s(s, 16);
in_uint8(s, codec_id);
in_uint16_le(s, codec_properties_length);
len -= 16 + 1 + 2;
if (len < codec_properties_length)
{
g_writeln("xrdp_caps_process_codecs: error");
return 1;
}
len -= codec_properties_length;
next_guid = s->p + codec_properties_length;
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
{
g_writeln("xrdp_caps_process_codecs: nscodec codec id %d prop len %d",
codec_id, codec_properties_length);
self->client_info.ns_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
g_memcpy(self->client_info.ns_prop, s->p, i1);
self->client_info.ns_prop_len = i1;
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
{
g_writeln("xrdp_caps_process_codecs: rfx codec id %d prop len %d",
codec_id, codec_properties_length);
self->client_info.rfx_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
g_memcpy(self->client_info.rfx_prop, s->p, i1);
self->client_info.rfx_prop_len = i1;
}
else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
{
g_writeln("xrdp_caps_process_codecs: jpeg codec id %d prop len %d",
codec_id, codec_properties_length);
self->client_info.jpeg_codec_id = codec_id;
i1 = MIN(64, codec_properties_length);
g_memcpy(self->client_info.jpeg_prop, s->p, i1);
self->client_info.jpeg_prop_len = i1;
/* make sure that requested quality is between 0 to 100 */
if (self->client_info.jpeg_prop[0] < 0 || self->client_info.jpeg_prop[0] > 100)
{
g_writeln(" Warning: the requested jpeg quality (%d) is invalid,"
" falling back to default", self->client_info.jpeg_prop[0]);
self->client_info.jpeg_prop[0] = 75; /* use default */
}
g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]);
}
else
{
g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id);
}
s->p = next_guid;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s,
int len)
{
int MaxRequestSize;
in_uint32_le(s, MaxRequestSize);
self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
{
int cap_len;
int source_len;
int num_caps;
int index;
int type;
int len;
char *p;
DEBUG(("in xrdp_caps_process_confirm_active"));
in_uint8s(s, 4); /* rdp_shareid */
in_uint8s(s, 2); /* userid */
in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */
in_uint16_le(s, cap_len);
in_uint8s(s, source_len);
in_uint16_le(s, num_caps);
in_uint8s(s, 2); /* pad */
for (index = 0; index < num_caps; index++)
{
p = s->p;
if (!s_check_rem(s, 4))
{
g_writeln("xrdp_caps_process_confirm_active: error 1");
return 1;
}
in_uint16_le(s, type);
in_uint16_le(s, len);
if ((len < 4) || !s_check_rem(s, len - 4))
{
g_writeln("xrdp_caps_process_confirm_active: error len %d", len, s->end - s->p);
return 1;
}
len -= 4;
switch (type)
{
case RDP_CAPSET_GENERAL: /* 1 */
DEBUG(("RDP_CAPSET_GENERAL"));
xrdp_caps_process_general(self, s, len);
break;
case RDP_CAPSET_BITMAP: /* 2 */
DEBUG(("RDP_CAPSET_BITMAP"));
break;
case RDP_CAPSET_ORDER: /* 3 */
DEBUG(("RDP_CAPSET_ORDER"));
xrdp_caps_process_order(self, s, len);
break;
case RDP_CAPSET_BMPCACHE: /* 4 */
DEBUG(("RDP_CAPSET_BMPCACHE"));
xrdp_caps_process_bmpcache(self, s, len);
break;
case RDP_CAPSET_CONTROL: /* 5 */
DEBUG(("RDP_CAPSET_CONTROL"));
break;
case 6:
xrdp_caps_process_cache_v3_codec_id(self, s, len);
break;
case RDP_CAPSET_ACTIVATE: /* 7 */
DEBUG(("RDP_CAPSET_ACTIVATE"));
break;
case RDP_CAPSET_POINTER: /* 8 */
DEBUG(("RDP_CAPSET_POINTER"));
xrdp_caps_process_pointer(self, s, len);
break;
case RDP_CAPSET_SHARE: /* 9 */
DEBUG(("RDP_CAPSET_SHARE"));
break;
case RDP_CAPSET_COLCACHE: /* 10 */
DEBUG(("RDP_CAPSET_COLCACHE"));
break;
case 12: /* 12 */
DEBUG(("--12"));
break;
case 13: /* 13 */
xrdp_caps_process_input(self, s, len);
break;
case 14: /* 14 */
DEBUG(("--14"));
break;
case RDP_CAPSET_BRUSHCACHE: /* 15 */
xrdp_caps_process_brushcache(self, s, len);
break;
case 16: /* 16 */
DEBUG(("--16"));
break;
case 17: /* 17 */
DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE"));
xrdp_caps_process_offscreen_bmpcache(self, s, len);
break;
case RDP_CAPSET_BMPCACHE2: /* 19 */
DEBUG(("RDP_CAPSET_BMPCACHE2"));
xrdp_caps_process_bmpcache2(self, s, len);
break;
case 20: /* 20 */
DEBUG(("--20"));
break;
case 21: /* 21 */
DEBUG(("--21"));
break;
case 22: /* 22 */
DEBUG(("--22"));
break;
case 0x0017: /* 23 CAPSETTYPE_RAIL */
xrdp_caps_process_rail(self, s, len);
break;
case 0x0018: /* 24 CAPSETTYPE_WINDOW */
xrdp_caps_process_window(self, s, len);
break;
case 0x001A: /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
xrdp_caps_process_multifragmetupdate(self, s, len);
break;
case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */
xrdp_caps_process_codecs(self, s, len);
break;
default:
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
break;
}
s->p = p + len + 4;
}
DEBUG(("out xrdp_caps_process_confirm_active"));
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_caps_send_demand_active(struct xrdp_rdp *self)
{
struct stream *s;
int caps_count;
int caps_size;
int codec_caps_count;
int codec_caps_size;
int flags;
char *caps_count_ptr;
char *caps_size_ptr;
char *caps_ptr;
char *codec_caps_count_ptr;
char *codec_caps_size_ptr;
make_stream(s);
init_stream(s, 8192);
DEBUG(("in xrdp_caps_send_demand_active"));
if (xrdp_rdp_init(self, s) != 0)
{
free_stream(s);
return 1;
}
caps_count = 0;
out_uint32_le(s, self->share_id);
out_uint16_le(s, 4); /* 4 chars for RDP\0 */
/* 2 bytes size after num caps, set later */
caps_size_ptr = s->p;
out_uint8s(s, 2);
out_uint8a(s, "RDP", 4);
/* 4 byte num caps, set later */
caps_count_ptr = s->p;
out_uint8s(s, 4);
caps_ptr = s->p;
/* Output share capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_SHARE);
out_uint16_le(s, RDP_CAPLEN_SHARE);
out_uint16_le(s, self->mcs_channel);
out_uint16_be(s, 0xb5e2); /* 0x73e1 */
/* Output general capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */
out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */
out_uint16_le(s, 1); /* OS major type */
out_uint16_le(s, 3); /* OS minor type */
out_uint16_le(s, 0x200); /* Protocol version */
out_uint16_le(s, 0); /* pad */
out_uint16_le(s, 0); /* Compression types */
/* NO_BITMAP_COMPRESSION_HDR 0x0400
FASTPATH_OUTPUT_SUPPORTED 0x0001 */
if (self->client_info.use_fast_path & 1)
{
out_uint16_le(s, 0x401);
}
else
{
out_uint16_le(s, 0x400);
}
out_uint16_le(s, 0); /* Update capability */
out_uint16_le(s, 0); /* Remote unshare capability */
out_uint16_le(s, 0); /* Compression level */
out_uint16_le(s, 0); /* Pad */
/* Output bitmap capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */
out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */
out_uint16_le(s, self->client_info.bpp); /* Preferred BPP */
out_uint16_le(s, 1); /* Receive 1 BPP */
out_uint16_le(s, 1); /* Receive 4 BPP */
out_uint16_le(s, 1); /* Receive 8 BPP */
out_uint16_le(s, self->client_info.width); /* width */
out_uint16_le(s, self->client_info.height); /* height */
out_uint16_le(s, 0); /* Pad */
out_uint16_le(s, 1); /* Allow resize */
out_uint16_le(s, 1); /* bitmap compression */
out_uint16_le(s, 0); /* unknown */
out_uint16_le(s, 0); /* unknown */
out_uint16_le(s, 0); /* pad */
/* Output font capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_FONT); /* 14 */
out_uint16_le(s, RDP_CAPLEN_FONT); /* 4 */
/* Output order capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_ORDER); /* 3 */
out_uint16_le(s, RDP_CAPLEN_ORDER); /* 88(0x58) */
out_uint8s(s, 16);
out_uint32_be(s, 0x40420f00);
out_uint16_le(s, 1); /* Cache X granularity */
out_uint16_le(s, 20); /* Cache Y granularity */
out_uint16_le(s, 0); /* Pad */
out_uint16_le(s, 1); /* Max order level */
out_uint16_le(s, 0x2f); /* Number of fonts */
out_uint16_le(s, 0x22); /* Capability flags */
/* caps */
out_uint8(s, 1); /* NEG_DSTBLT_INDEX 0x00 0 */
out_uint8(s, 1); /* NEG_PATBLT_INDEX 0x01 1 */
out_uint8(s, 1); /* NEG_SCRBLT_INDEX 0x02 2 */
out_uint8(s, 1); /* NEG_MEMBLT_INDEX 0x03 3 */
out_uint8(s, 0); /* NEG_MEM3BLT_INDEX 0x04 4 */
out_uint8(s, 0); /* NEG_ATEXTOUT_INDEX 0x05 5 */
out_uint8(s, 0); /* NEG_AEXTTEXTOUT_INDEX 0x06 6 */
out_uint8(s, 0); /* NEG_DRAWNINEGRID_INDEX 0x07 7 */
out_uint8(s, 1); /* NEG_LINETO_INDEX 0x08 8 */
out_uint8(s, 0); /* NEG_MULTI_DRAWNINEGRID_INDEX 0x09 9 */
out_uint8(s, 1); /* NEG_OPAQUE_RECT_INDEX 0x0A 10 */
out_uint8(s, 0); /* NEG_SAVEBITMAP_INDEX 0x0B 11 */
out_uint8(s, 0); /* NEG_WTEXTOUT_INDEX 0x0C 12 */
out_uint8(s, 0); /* NEG_MEMBLT_V2_INDEX 0x0D 13 */
out_uint8(s, 0); /* NEG_MEM3BLT_V2_INDEX 0x0E 14 */
out_uint8(s, 0); /* NEG_MULTIDSTBLT_INDEX 0x0F 15 */
out_uint8(s, 0); /* NEG_MULTIPATBLT_INDEX 0x10 16 */
out_uint8(s, 0); /* NEG_MULTISCRBLT_INDEX 0x11 17 */
out_uint8(s, 1); /* NEG_MULTIOPAQUERECT_INDEX 0x12 18 */
out_uint8(s, 0); /* NEG_FAST_INDEX_INDEX 0x13 19 */
out_uint8(s, 0); /* NEG_POLYGON_SC_INDEX 0x14 20 */
out_uint8(s, 0); /* NEG_POLYGON_CB_INDEX 0x15 21 */
out_uint8(s, 0); /* NEG_POLYLINE_INDEX 0x16 22 */
out_uint8(s, 0); /* unused 0x17 23 */
out_uint8(s, 0); /* NEG_FAST_GLYPH_INDEX 0x18 24 */
out_uint8(s, 0); /* NEG_ELLIPSE_SC_INDEX 0x19 25 */
out_uint8(s, 0); /* NEG_ELLIPSE_CB_INDEX 0x1A 26 */
out_uint8(s, 1); /* NEG_GLYPH_INDEX_INDEX 0x1B 27 */
out_uint8(s, 0); /* NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C 28 */
out_uint8(s, 0); /* NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D 29 */
out_uint8(s, 0); /* NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E 30 */
out_uint8(s, 0); /* unused 0x1F 31 */
out_uint16_le(s, 0x6a1);
/* declare support of bitmap cache rev3 */
out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT);
out_uint32_le(s, 0x0f4240); /* desk save */
out_uint32_le(s, 0x0f4240); /* desk save */
out_uint32_le(s, 1); /* ? */
out_uint32_le(s, 0); /* ? */
/* Output bmpcodecs capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_BMPCODECS);
codec_caps_size_ptr = s->p;
out_uint8s(s, 2); /* cap len set later */
codec_caps_count = 0;
codec_caps_count_ptr = s->p;
out_uint8s(s, 1); /* bitmapCodecCount set later */
/* nscodec */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16);
out_uint8(s, 1); /* codec id, must be 1 */
out_uint16_le(s, 3);
out_uint8(s, 0x01); /* fAllowDynamicFidelity */
out_uint8(s, 0x01); /* fAllowSubsampling */
out_uint8(s, 0x03); /* colorLossLevel */
/* remotefx */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16);
out_uint8(s, 0); /* codec id, client sets */
out_uint16_le(s, 256);
out_uint8s(s, 256);
/* jpeg */
codec_caps_count++;
out_uint8a(s, XR_CODEC_GUID_JPEG, 16);
out_uint8(s, 0); /* codec id, client sets */
out_uint16_le(s, 1); /* ext length */
out_uint8(s, 75);
/* calculate and set size and count */
codec_caps_size = (int)(s->p - codec_caps_size_ptr);
codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */
codec_caps_size_ptr[0] = codec_caps_size;
codec_caps_size_ptr[1] = codec_caps_size >> 8;
codec_caps_count_ptr[0] = codec_caps_count;
/* Output color cache capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_COLCACHE);
out_uint16_le(s, RDP_CAPLEN_COLCACHE);
out_uint16_le(s, 6); /* cache size */
out_uint16_le(s, 0); /* pad */
/* Output pointer capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_POINTER);
out_uint16_le(s, RDP_CAPLEN_POINTER);
out_uint16_le(s, 1); /* Colour pointer */
out_uint16_le(s, 0x19); /* Cache size */
out_uint16_le(s, 0x19); /* Cache size */
/* Output input capability set */
caps_count++;
out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */
out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */
/* INPUT_FLAG_SCANCODES 0x0001
INPUT_FLAG_MOUSEX 0x0004
INPUT_FLAG_FASTPATH_INPUT 0x0008
INPUT_FLAG_FASTPATH_INPUT2 0x0020 */
flags = 0x0001 | 0x0004;
if (self->client_info.use_fast_path & 2)
{
/* 0x0008 INPUT_FLAG_FASTPATH_INPUT */
/* 0x0020 INPUT_FLAG_FASTPATH_INPUT2 */
flags |= 0x0008 | 0x0020;
}
out_uint16_le(s, flags);
out_uint8s(s, 82);
/* Remote Programs Capability Set */
caps_count++;
out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */
out_uint16_le(s, 8);
out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED
TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */
/* Window List Capability Set */
caps_count++;
out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */
out_uint16_le(s, 11);
out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */
out_uint8(s, 3); /* NumIconCaches */
out_uint16_le(s, 12); /* NumIconCacheEntries */
/* 6 - bitmap cache v3 codecid */
caps_count++;
out_uint16_le(s, 0x0006);
out_uint16_le(s, 5);
out_uint8(s, 0); /* client sets */
if (self->client_info.use_fast_path & 1) /* fastpath output on */
{
caps_count++;
out_uint16_le(s, 0x001A); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */
out_uint16_le(s, 8);
out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */
}
out_uint8s(s, 4); /* pad */
s_mark_end(s);
caps_size = (int)(s->end - caps_ptr);
caps_size_ptr[0] = caps_size;
caps_size_ptr[1] = caps_size >> 8;
caps_count_ptr[0] = caps_count;
caps_count_ptr[1] = caps_count >> 8;
caps_count_ptr[2] = caps_count >> 16;
caps_count_ptr[3] = caps_count >> 24;
if (xrdp_rdp_send(self, s, RDP_PDU_DEMAND_ACTIVE) != 0)
{
free_stream(s);
return 1;
}
DEBUG(("out (1) xrdp_caps_send_demand_active"));
/* send Monitor Layout PDU for dual monitor */
if (self->client_info.monitorCount > 0 &&
self->client_info.multimon == 1)
{
DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu"));
if (xrdp_caps_send_monitorlayout(self) != 0)
{
g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu");
}
}
free_stream(s);
return 0;
}

@ -105,10 +105,21 @@ xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
s_pop_layer(s, channel_hdr);
out_uint32_le(s, total_data_len);
if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
{
flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
}
/*
* According to 2.2.1.3.4.1 Channel Definition Structure (CHANNEL_DEF):
* CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
* The value of this flag MUST be ignored by the server. The
* visibility of the Channel PDU Header (section 2.2.6.1.1) is
* determined by the CHANNEL_FLAG_SHOW_PROTOCOL
* (0x00000010) flag as defined in the flags field (section
* 2.2.6.1.1).
*
* That's flag makes MSTSC crash when using RAIL channel.
*/
// if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
// {
// flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
// }
out_uint32_le(s, flags);

@ -1,8 +1,8 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2012-2013
* Copyright (C) Kevin Zhou 2012
* Copyright (C) Jay Sorg 2012-2014
* Copyright (C) Idan Freiberg 2013-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,16 +21,16 @@
/*****************************************************************************/
struct xrdp_fastpath *APP_CC
xrdp_fastpath_create(struct xrdp_session *session)
xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
{
struct xrdp_fastpath *self;
DEBUG((" in xrdp_fastpath_create"));
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
self->tcp_layer =
((struct xrdp_rdp *)session->rdp)->sec_layer->
mcs_layer->iso_layer->tcp_layer;
make_stream(self->out_s);
init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE);
self->sec_layer = owner;
self->trans = trans;
self->session = owner->rdp_layer->session;
DEBUG((" out xrdp_fastpath_create"));
return self;
}
@ -42,8 +42,6 @@ xrdp_fastpath_delete(struct xrdp_fastpath *self)
{
return;
}
free_stream(self->out_s);
g_free(self);
}
@ -55,155 +53,306 @@ xrdp_fastpath_reset(struct xrdp_fastpath *self)
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_fastpath_init(struct xrdp_fastpath *self)
xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
{
int fp_hdr;
int len = 0; /* unused */
int byte;
char *holdp;
DEBUG((" in xrdp_fastpath_recv"));
holdp = s->p;
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */
in_uint8(s, byte); /* length 1 (1 byte) */
self->numEvents = (fp_hdr & 0x3C) >> 2;
self->secFlags = (fp_hdr & 0xC0) >> 6;
if (byte & 0x80)
{
byte &= ~(0x80);
len = (byte << 8);
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, byte); /* length 2 (1 byte) */
len += byte;
}
else
{
len = byte;
}
s->next_packet = holdp + len;
DEBUG((" out xrdp_fastpath_recv"));
return 0;
}
/*****************************************************************************/
/* no fragmenation */
int APP_CC
xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode,
struct stream *s)
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
{
tui16 len;
tui16 maxLen;
tui32 payloadLeft;
tui8 fragment;
struct stream *s_send;
int compression;
int i;
int i32;
int bytes;
compression = 0;
s_send = self->out_s;
maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */
payloadLeft = (s->end - s->data);
bytes = self->session->client_info->max_fastpath_frag_bytes;
if (bytes < 32 * 1024)
{
bytes = 32 * 1024;
}
init_stream(s, bytes);
return 0;
}
for (i = 0; payloadLeft > 0; i++)
/*****************************************************************************/
/* no fragmenation */
int APP_CC
xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
{
if (trans_force_write_s(self->trans, s) != 0)
{
if (payloadLeft > maxLen)
{
len = maxLen;
}
else
{
len = payloadLeft;
}
return 1;
}
return 0;
}
payloadLeft -= len;
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */
int APP_CC
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int flags;
int code;
flags = 0;
if (payloadLeft == 0)
{
fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE;
}
else
{
fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST;
}
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, code); /* keyCode (1 byte) */
init_stream(s_send, 0);
out_uint8(s_send, 0); /* fOutputHeader */
i32 = ((len + 6) >> 8) | 0x80;
out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */
i32 = (len + 6) & 0xff;
out_uint8(s_send, i32);
i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) |
((compression & 0x03) << 6);
out_uint8(s_send, i32);
out_uint16_le(s_send, len);
s_copy(s_send, s, len);
s_mark_end(s_send);
if (xrdp_tcp_send(self->tcp_layer, s_send) != 0)
{
return 1;
}
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
{
flags |= KBD_FLAG_UP;
}
else
{
flags |= KBD_FLAG_DOWN;
}
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
flags |= KBD_FLAG_EXT;
if (self->session->callback != 0)
{
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0,
flags, 0);
}
return 0;
}
/*****************************************************************************/
int
xrdp_fastpath_process_update(struct xrdp_fastpath *self, tui8 updateCode,
tui32 size, struct stream *s)
/* FASTPATH_INPUT_EVENT_MOUSE */
int APP_CC
xrdp_fastpath_process_EVENT_MOUSE(struct xrdp_fastpath *self, int eventFlags,
struct stream *s)
{
switch (updateCode)
{
case FASTPATH_UPDATETYPE_ORDERS:
case FASTPATH_UPDATETYPE_BITMAP:
case FASTPATH_UPDATETYPE_PALETTE:
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
case FASTPATH_UPDATETYPE_SURFCMDS:
case FASTPATH_UPDATETYPE_PTR_NULL:
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
case FASTPATH_UPDATETYPE_PTR_POSITION:
case FASTPATH_UPDATETYPE_COLOR:
case FASTPATH_UPDATETYPE_CACHED:
case FASTPATH_UPDATETYPE_POINTER:
break;
default:
g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X",
updateCode);
break;
int pointerFlags;
int xPos;
int yPos;
/* eventFlags MUST be zeroed out */
if (eventFlags != 0)
{
return 1;
}
if (!s_check_rem(s, 2 + 2 + 2))
{
return 1;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
if (self->session->callback != 0)
{
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, RDP_INPUT_MOUSE,
xPos, yPos, pointerFlags, 0);
}
return 0;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_MOUSEX */
int APP_CC
xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s,
tui8 header)
xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
tui8 encryptionFlags;
tui8 numberEvents;
tui8 length2;
tui8 updateHeader;
tui8 updateCode;
tui8 updateFrag;
tui8 updateComp;
tui16 length;
tui32 size;
encryptionFlags = (header & 0xc0) >> 6;
numberEvents = (header & 0x3c) >> 2;
xrdp_tcp_recv(self->tcp_layer, s, 1);
in_uint8(s, length);
if (length & 0x80)
{
xrdp_tcp_recv(self->tcp_layer, s, 1);
in_uint8(s, length2);
length = (length & 0x7f) << 8 + length2 - 3;
int pointerFlags;
int xPos;
int yPos;
/* eventFlags MUST be zeroed out */
if (eventFlags != 0)
{
return 1;
}
else
if (!s_check_rem(s, 2 + 2 + 2))
{
length -= 2;
return 1;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
xrdp_tcp_recv(self->tcp_layer, s, length);
if (self->session->callback != 0)
{
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, RDP_INPUT_MOUSEX,
xPos, yPos, pointerFlags, 0);
}
return 0;
}
if (encryptionFlags != 0)
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SYNC */
int APP_CC
xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventCode,
int eventFlags, struct stream *s)
{
/*
* The eventCode bitfield (3 bits in size) MUST be set to
* FASTPATH_INPUT_EVENT_SYNC (3).
* The eventFlags bitfield (5 bits in size) contains flags
* indicating the "on"
* status of the keyboard toggle keys.
*/
if (self->session->callback != 0)
{
/* TODO decryption ...*/
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE,
eventCode, 0, eventFlags, 0);
}
return 0;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_UNICODE */
int APP_CC
xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8s(s, 2);
return 0;
}
/* parse updateHeader */
in_uint8(s, updateHeader);
updateCode = (updateHeader & 0x0f);
updateFrag = (updateHeader & 0x30) >> 4;
updateComp = (updateHeader & 0xc0) >> 6;
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT */
int APP_CC
xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s)
{
int i;
int eventHeader;
int eventCode;
int eventFlags;
if (updateFrag && updateComp)
/* process fastpath input events */
for (i = 0; i < self->numEvents; i++)
{
/* TODO */
g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d",
updateFrag, updateComp);
return 1;
}
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, eventHeader);
eventFlags = (eventHeader & 0x1F);
eventCode = (eventHeader >> 5);
switch (eventCode)
{
case FASTPATH_INPUT_EVENT_SCANCODE:
if (xrdp_fastpath_process_EVENT_SCANCODE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
in_uint16_le(s, size);
return xrdp_fastpath_process_update(self, updateCode, size, s);
case FASTPATH_INPUT_EVENT_MOUSE:
if (xrdp_fastpath_process_EVENT_MOUSE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_MOUSEX:
if (xrdp_fastpath_process_EVENT_MOUSEX(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_SYNC:
if (xrdp_fastpath_process_EVENT_SYNC(self, eventCode,
eventFlags,
s) != 0)
{
return 1;
}
break;
case FASTPATH_INPUT_EVENT_UNICODE:
if (xrdp_fastpath_process_EVENT_UNICODE(self,
eventFlags,
s) != 0)
{
return 1;
}
break;
default:
g_writeln("xrdp_fastpath_process_input_event: unknown "
"eventCode %d", eventCode);
break;
}
}
return 0;
}

@ -1,8 +1,8 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Idan Freiberg 2013
* Copyright (C) Jay Sorg 2004-2014
* Copyright (C) Idan Freiberg 2013-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,13 +22,14 @@
#include "libxrdp.h"
/*****************************************************************************/
struct xrdp_iso *APP_CC
struct xrdp_iso *
APP_CC
xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
{
struct xrdp_iso *self;
DEBUG((" in xrdp_iso_create"));
self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1);
self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
self->mcs_layer = owner;
self->trans = trans;
DEBUG((" out xrdp_iso_create"));
@ -50,37 +51,33 @@ xrdp_iso_delete(struct xrdp_iso *self)
/*****************************************************************************/
/* returns error */
static int APP_CC
xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s)
xrdp_iso_process_rdpNegReq(struct xrdp_iso *self, struct stream *s)
{
int flags;
int len;
DEBUG((" in xrdp_iso_recv_rdpnegreq"));
in_uint8(s, flags);
if (flags != 0x0)
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
{
DEBUG((" xrdp_iso_recv_rdpnegreq: flags: %x",flags));
DEBUG(("xrdp_iso_process_rdpNegReq: error, flags: %x",flags));
return 1;
}
in_uint16_le(s, len);
if (len != 8) // fixed length
if (len != 8)
{
DEBUG((" xrdp_iso_recv_rdpnegreq: length: %x",len));
DEBUG(("xrdp_iso_process_rdpNegReq: error, length: %x",len));
return 1;
}
in_uint32_le(s, self->requestedProtocol);
if (self->requestedProtocol > 0xb)
{
DEBUG(("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
self->requestedProtocol));
return 1;
}
//TODO: think of protocol verification logic
// if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX)
// {
// DEBUG((" xrdp_iso_recv_rdpnegreq: wrong requestedProtocol: %x",requestedProtocol));
// return 1;
// }
DEBUG((" out xrdp_iso_recv_rdpnegreq"));
return 0;
}
/*****************************************************************************/
@ -88,29 +85,23 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s)
static int APP_CC
xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
{
int ver; // TPKT Version
int plen; // TPKT PacketLength
int do_read;
*code = 0; // X.224 Packet Type
*len = 0; // X.224 Length Indicator
int ver; // tpkt ver
int plen; // tpkt len
/* early in connection sequence, iso needs to do a force read */
do_read = s != self->trans->in_s;
*code = 0; // x.244 type
*len = 0; // X.224 len indicator
if (do_read)
if (s != self->trans->in_s)
{
init_stream(s, 4);
if (trans_force_read_s(self->trans, s, 4) != 0)
{
return 1;
}
g_writeln("xrdp_iso_recv_msg error logic");
}
in_uint8(s, ver);
if (ver != 3)
{
g_writeln("xrdp_iso_recv_msg: bad ver");
g_hexdump(s->data, 4);
return 1;
}
@ -122,15 +113,6 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
return 1;
}
if (do_read)
{
init_stream(s, plen - 4);
if (trans_force_read_s(self->trans, s, plen - 4) != 0)
{
return 1;
}
}
if (!s_check_rem(s, 2))
{
return 1;
@ -184,120 +166,70 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
DEBUG((" out xrdp_iso_recv"));
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code)
xrdp_iso_send_cc(struct xrdp_iso *self)
{
init_stream(s, 8192 * 4); /* 32 KB */
struct stream *s;
char *holdp;
char *len_ptr;
char *len_indicator_ptr;
int len;
int len_indicator;
/* TPKT HEADER - 4 bytes */
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* RESERVED */
if (self->selectedProtocol != -1)
{
out_uint16_be(s, 19); /* length */ //rdp negotiation happens.
}
else
{
out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen.
}
/* ISO LAYER - X.224 - 7 bytes*/
if (self->selectedProtocol != -1)
{
out_uint8(s, 14); /* length */
}
else
{
out_uint8(s, 6); /* length */
}
out_uint8(s, code); /* SHOULD BE 0xD for CC */
make_stream(s);
init_stream(s, 8192);
holdp = s->p;
/* tpkt */
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* pad */
len_ptr = s->p;
out_uint16_be(s, 0); /* length, set later */
/* iso */
len_indicator_ptr = s->p;
out_uint8(s, 0); /* length indicator, set later */
out_uint8(s, ISO_PDU_CC); /* Connection Confirm PDU */
out_uint16_be(s, 0);
out_uint16_be(s, 0x1234);
out_uint8(s, 0);
if (self->selectedProtocol != -1)
/* rdpNegData */
if (self->rdpNegData)
{
/* RDP_NEG_RSP - 8 bytes*/
out_uint8(s, RDP_NEG_RSP);
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
out_uint16_le(s, 8); /* fixed length */
out_uint32_le(s, self->selectedProtocol); /* selected protocol */
if (self->failureCode)
{
out_uint8(s, RDP_NEG_FAILURE);
out_uint8(s, 0); /* no flags */
out_uint16_le(s, 8); /* must be 8 */
out_uint32_le(s, self->failureCode); /* failure code */
}
else
{
out_uint8(s, RDP_NEG_RSP);
//TODO: hardcoded flags
out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */
out_uint16_le(s, 8); /* must be 8 */
out_uint32_le(s, self->selectedProtocol); /* selected protocol */
}
}
s_mark_end(s);
if (trans_force_write_s(self->trans, s) != 0)
{
return 1;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode)
{
init_stream(s, 8192 * 4); /* 32 KB */
/* TPKT HEADER - 4 bytes */
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* RESERVED */
out_uint16_be(s, 19); /* length */
/* ISO LAYER - X.224 - 7 bytes*/
out_uint8(s, 14); /* length */
out_uint8(s, code); /* SHOULD BE 0xD for CC */
out_uint16_be(s, 0);
out_uint16_be(s, 0x1234);
out_uint8(s, 0);
/* RDP_NEG_FAILURE - 8 bytes*/
out_uint8(s, RDP_NEG_FAILURE);
out_uint8(s, 0); /* no flags available */
out_uint16_le(s, 8); /* fixed length */
out_uint32_le(s, failureCode); /* failure code */
s_mark_end(s);
len = (int) (s->end - holdp);
len_indicator = (int) (s->end - len_indicator_ptr) - 1;
len_ptr[0] = len >> 8;
len_ptr[1] = len;
len_indicator_ptr[0] = len_indicator;
if (trans_force_write_s(self->trans, s) != 0)
{
free_stream(s);
return 1;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_iso_send_nego(struct xrdp_iso *self)
{
struct stream *s;
make_stream(s);
init_stream(s, 8192);
//TODO: negotiation logic here.
if (self->requestedProtocol != PROTOCOL_RDP)
{
// Send RDP_NEG_FAILURE back to client
if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC,
SSL_NOT_ALLOWED_BY_SERVER) != 0)
{
free_stream(s);
return 1;
}
}
else
{
self->selectedProtocol = PROTOCOL_RDP;
// Send RDP_NEG_RSP back to client
if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0)
{
free_stream(s);
return 1;
}
}
free_stream(s);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
@ -311,26 +243,26 @@ xrdp_iso_incoming(struct xrdp_iso *self)
char *pend;
struct stream *s;
make_stream(s);
init_stream(s, 8192);
DEBUG((" in xrdp_iso_incoming"));
s = libxrdp_force_read(self->trans);
if (s == 0)
{
return 1;
}
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
{
DEBUG((" in xrdp_iso_recv_msg error!!"));
free_stream(s);
g_writeln("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero");
return 1;
}
if ((code != ISO_PDU_CR) || (len < 6))
{
free_stream(s);
return 1;
}
self->selectedProtocol = -1;
self->requestedProtocol = PROTOCOL_RDP;
/* process connection request */
pend = s->p + (len - 6);
cookie_index = 0;
while (s->p < pend)
@ -341,9 +273,10 @@ xrdp_iso_incoming(struct xrdp_iso *self)
default:
break;
case RDP_NEG_REQ: /* rdpNegReq 1 */
if (xrdp_iso_recv_rdpnegreq(self, s) != 0)
self->rdpNegData = 1;
if (xrdp_iso_process_rdpNegReq(self, s) != 0)
{
free_stream(s);
g_writeln("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero");
return 1;
}
break;
@ -369,14 +302,87 @@ xrdp_iso_incoming(struct xrdp_iso *self)
}
}
if (xrdp_iso_send_nego(self) != 0)
int serverSecurityLayer = self->mcs_layer->sec_layer->rdp_layer->client_info.security_layer;
/* security layer negotiation */
if (self->rdpNegData)
{
free_stream(s);
self->selectedProtocol = PROTOCOL_RDP; /* set default security layer */
switch (serverSecurityLayer)
{
case (PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX):
/* server supports tls+hybrid+hybrid_ex */
if (self->requestedProtocol == (PROTOCOL_SSL | PROTOCOL_HYBRID
| PROTOCOL_HYBRID_EX))
{
/* client supports tls+hybrid+hybrid_ex */
self->selectedProtocol = PROTOCOL_SSL; //TODO: change
}
else
{
self->failureCode = SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER;
}
break;
case (PROTOCOL_SSL | PROTOCOL_HYBRID):
/* server supports tls+hybrid */
if (self->requestedProtocol == (PROTOCOL_SSL | PROTOCOL_HYBRID))
{
/* client supports tls+hybrid */
self->selectedProtocol = PROTOCOL_SSL; //TODO: change
}
else
{
self->failureCode = HYBRID_REQUIRED_BY_SERVER;
}
break;
case PROTOCOL_SSL:
/* server supports tls */
if (self->requestedProtocol & PROTOCOL_SSL) //TODO
{
/* client supports tls */
self->selectedProtocol = PROTOCOL_SSL;
}
else
{
self->failureCode = SSL_REQUIRED_BY_SERVER;
}
break;
case PROTOCOL_RDP:
/* server supports rdp */
if (self->requestedProtocol == PROTOCOL_RDP)
{
/* client supports rdp */
self->selectedProtocol = PROTOCOL_RDP;
}
else
{
self->failureCode = SSL_NOT_ALLOWED_BY_SERVER;
}
break;
default:
/* unsupported protocol */
g_writeln("xrdp_iso_incoming: unsupported protocol %d",
self->requestedProtocol);
self->failureCode = INCONSISTENT_FLAGS; //TODO: ?
}
}
else if (self->requestedProtocol != serverSecurityLayer)
{
/* enforce server security */
return 1;
}
/* set things for tls connection */
/* send connection confirm back to client */
if (xrdp_iso_send_cc(self) != 0)
{
g_writeln("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero");
return 1;
}
DEBUG((" out xrdp_iso_incoming"));
free_stream(s);
return 0;
}
@ -399,7 +405,7 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
DEBUG((" in xrdp_iso_send"));
s_pop_layer(s, iso_hdr);
len = (int)(s->end - s->p);
len = (int) (s->end - s->p);
out_uint8(s, 3);
out_uint8(s, 0);
out_uint16_be(s, len);

@ -120,10 +120,11 @@ xrdp_codec_jpeg_compress(void *handle,
/* len of compressed data */
)
{
tjhandle tj_han;
int error;
int bpp;
char *src_ptr;
tjhandle tj_han;
int error;
int bpp;
char *src_ptr;
unsigned long lio_len;
/*
* note: for now we assume that format is always XBGR and ignore format
@ -143,7 +144,21 @@ xrdp_codec_jpeg_compress(void *handle,
/* start of inner rect in inp_data */
src_ptr = inp_data + (y * stride + x * bpp);
lio_len = *io_len;
/* compress inner rect */
/* notes
* TJPF_RGB no works, zero bytes
* TJPF_BGR no works, not zero but no open
* TJPF_RGBX no works, zero bytes
* TJPF_BGRX no works, off scaled image
* TJPF_XBGR works
* TJPF_XRGB no works, zero bytes
* TJPF_RGBA no works, zero bytes
* TJPF_BGRA no works, zero bytes
* TJPF_ABGR no works, zero bytes
* TJPF_ARGB no works, zero bytes */
error = tjCompress(tj_han, /* opaque handle */
src_ptr, /* source buf */
cx, /* width of area to compress */
@ -151,11 +166,12 @@ xrdp_codec_jpeg_compress(void *handle,
cy, /* height of area to compress */
TJPF_XBGR, /* pixel size */
out_data, /* dest buf */
io_len, /* inner_buf length & compressed_size */
&lio_len, /* inner_buf length & compressed_size */
TJSAMP_420, /* jpeg sub sample */
quality, /* jpeg quality */
0 /* flags */
);
*io_len = lio_len;
return height;
}
@ -381,6 +397,15 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
return height;
}
/*****************************************************************************/
int APP_CC
xrdp_codec_jpeg_compress(void *handle, int format, char *inp_data, int width,
int height, int stride, int x, int y, int cx, int cy,
int quality, char *out_data, int *io_len)
{
return 0;
}
/*****************************************************************************/
void *APP_CC
xrdp_jpeg_init(void)
@ -407,6 +432,15 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
return height;
}
/*****************************************************************************/
int APP_CC
xrdp_codec_jpeg_compress(void *handle, int format, char *inp_data, int width,
int height, int stride, int x, int y, int cx, int cy,
int quality, char *out_data, int *io_len)
{
return 0;
}
/*****************************************************************************/
void *APP_CC
xrdp_jpeg_init(void)

@ -122,14 +122,14 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
int len;
int userid;
int chanid;
DEBUG((" in xrdp_mcs_recv"));
while (1)
{
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero"));
DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero"));
g_writeln("xrdp_mcs_recv: xrdp_iso_recv failed");
return 1;
}
@ -151,12 +151,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
/* this is channels getting added from the client */
if (appid == MCS_CJRQ)
{
if (s == self->iso_layer->trans->in_s)
{
/* this should not happen */
g_writeln("xrdp_mcs_recv: error, MCS_CJRQ at wrong time");
return 1;
}
if (!s_check_rem(s, 4))
{
return 1;
@ -171,6 +166,14 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
{
log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
}
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
g_writeln("xrdp_mcs_recv: libxrdp_force_read failed");
return 1;
}
continue;
}
@ -322,30 +325,29 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
int len;
struct stream *s;
make_stream(s);
init_stream(s, 16 * 1024);
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0)
{
free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
@ -353,13 +355,11 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
@ -367,13 +367,11 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0)
{
free_stream(s);
return 1;
}
if ((len < 0) || !s_check_rem(s, len))
{
free_stream(s);
return 1;
}
@ -381,38 +379,32 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
free_stream(s);
return 1;
}
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
free_stream(s);
return 1;
}
if (xrdp_mcs_parse_domain_params(self, s) != 0)
{
free_stream(s);
return 1;
}
if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0)
{
free_stream(s);
return 1;
}
/* mcs data can not be zero length */
if ((len <= 0) || (len > 16 * 1024))
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, len))
{
free_stream(s);
return 1;
}
@ -424,12 +416,10 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self)
if (s_check_end(s))
{
free_stream(s);
return 0;
}
else
{
free_stream(s);
return 1;
}
}
@ -443,18 +433,20 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
struct stream *s;
DEBUG((" in xrdp_mcs_recv_edrq"));
make_stream(s);
init_stream(s, 8192);
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
@ -462,13 +454,11 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_EDRQ)
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, 4))
{
free_stream(s);
return 1;
}
@ -479,7 +469,6 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint16_be(s, self->userid);
@ -487,11 +476,9 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
free_stream(s);
return 1;
}
free_stream(s);
DEBUG((" out xrdp_mcs_recv_edrq"));
return 0;
}
@ -505,18 +492,20 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
struct stream *s;
DEBUG((" in xrdp_mcs_recv_aurq"));
make_stream(s);
init_stream(s, 8192);
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
@ -524,7 +513,6 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_AURQ)
{
free_stream(s);
return 1;
}
@ -532,7 +520,6 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint16_be(s, self->userid);
@ -540,11 +527,9 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
free_stream(s);
return 1;
}
free_stream(s);
DEBUG((" out xrdp_mcs_recv_aurq"));
return 0;
}
@ -592,18 +577,19 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
int opcode;
struct stream *s;
make_stream(s);
init_stream(s, 8192);
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
{
return 1;
}
if (xrdp_iso_recv(self->iso_layer, s) != 0)
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, 1))
{
free_stream(s);
return 1;
}
@ -611,13 +597,11 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
if ((opcode >> 2) != MCS_CJRQ)
{
free_stream(s);
return 1;
}
if (!s_check_rem(s, 4))
{
free_stream(s);
return 1;
}
@ -627,7 +611,6 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
{
if (!s_check_rem(s, 2))
{
free_stream(s);
return 1;
}
in_uint8s(s, 2);
@ -635,11 +618,9 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
if (!(s_check_end(s)))
{
free_stream(s);
return 1;
}
free_stream(s);
return 0;
}
@ -725,7 +706,163 @@ xrdp_mcs_out_domain_params(struct xrdp_mcs *self, struct stream *s,
xrdp_mcs_ber_out_int8(self, s, 2);
return 0;
}
/*****************************************************************************/
/* prepare server gcc data to send in mcs response msg */
int APP_CC
xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
{
struct stream *s;
int num_channels_even;
int num_channels;
int index;
int channel;
int gcc_size;
char* gcc_size_ptr;
char* ud_ptr;
num_channels = self->mcs_layer->channel_list->count;
num_channels_even = num_channels + (num_channels & 1);
s = &(self->server_mcs_data);
init_stream(s, 8192);
out_uint16_be(s, 5); /* AsnBerObjectIdentifier */
out_uint16_be(s, 0x14);
out_uint8(s, 0x7c);
out_uint16_be(s, 1); /* -- */
out_uint8(s, 0x2a); /* ConnectPDULen */
out_uint8(s, 0x14);
out_uint8(s, 0x76);
out_uint8(s, 0x0a);
out_uint8(s, 1);
out_uint8(s, 1);
out_uint8(s, 0);
out_uint16_le(s, 0xc001);
out_uint8(s, 0);
out_uint8(s, 0x4d); /* M */
out_uint8(s, 0x63); /* c */
out_uint8(s, 0x44); /* D */
out_uint8(s, 0x6e); /* n */
/* GCC Response Total Length - 2 bytes , set later */
gcc_size_ptr = s->p; /* RDPGCCUserDataResponseLength */
out_uint8s(s, 2);
ud_ptr = s->p; /* User Data */
out_uint16_le(s, SEC_TAG_SRV_INFO);
if (self->mcs_layer->iso_layer->rdpNegData)
{
out_uint16_le(s, 12); /* len */
}
else
{
out_uint16_le(s, 8); /* len */
}
out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */
out_uint8(s, 0);
out_uint8(s, 8);
out_uint8(s, 0);
if (self->mcs_layer->iso_layer->rdpNegData)
{
/* ReqeustedProtocol */
out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol);
}
out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */
out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */
out_uint16_le(s, num_channels); /* number of other channels */
for (index = 0; index < num_channels_even; index++)
{
if (index < num_channels)
{
channel = MCS_GLOBAL_CHANNEL + (index + 1);
out_uint16_le(s, channel);
}
else
{
out_uint16_le(s, 0);
}
}
if (self->rsa_key_bytes == 64)
{
g_writeln("xrdp_sec_out_mcs_data: using 512 bit RSA key");
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x00ec); /* len is 236 */
out_uint32_le(s, self->crypt_method);
out_uint32_le(s, self->crypt_level);
out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32);
/* here to end is certificate */
/* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */
/* TermService\Parameters\Certificate */
out_uint32_le(s, 1);
out_uint32_le(s, 1);
out_uint32_le(s, 1);
out_uint16_le(s, SEC_TAG_PUBKEY); /* 0x0006 */
out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */
out_uint32_le(s, SEC_RSA_MAGIC); /* 0x31415352 'RSA1' */
out_uint32_le(s, 0x0048); /* 72 bytes modulus len */
out_uint32_be(s, 0x00020000); /* bit len */
out_uint32_be(s, 0x3f000000); /* data len */
out_uint8a(s, self->pub_exp, 4); /* pub exp */
out_uint8a(s, self->pub_mod, 64); /* pub mod */
out_uint8s(s, 8); /* pad */
out_uint16_le(s, SEC_TAG_KEYSIG); /* 0x0008 */
out_uint16_le(s, 72); /* len */
out_uint8a(s, self->pub_sig, 64); /* pub sig */
out_uint8s(s, 8); /* pad */
}
else if (self->rsa_key_bytes == 256)
{
g_writeln("xrdp_sec_out_mcs_data: using 2048 bit RSA key");
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x01ac); /* len is 428 */
out_uint32_le(s, self->crypt_method);
out_uint32_le(s, self->crypt_level);
out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0x178); /* 376 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32);
/* here to end is certificate */
/* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */
/* TermService\Parameters\Certificate */
out_uint32_le(s, 1);
out_uint32_le(s, 1);
out_uint32_le(s, 1);
out_uint16_le(s, SEC_TAG_PUBKEY); /* 0x0006 */
out_uint16_le(s, 0x011c); /* 284 bytes length of SEC_TAG_PUBKEY */
out_uint32_le(s, SEC_RSA_MAGIC); /* 0x31415352 'RSA1' */
out_uint32_le(s, 0x0108); /* 264 bytes modulus len */
out_uint32_be(s, 0x00080000); /* bit len */
out_uint32_be(s, 0xff000000); /* data len */
out_uint8a(s, self->pub_exp, 4); /* pub exp */
out_uint8a(s, self->pub_mod, 256); /* pub mod */
out_uint8s(s, 8); /* pad */
out_uint16_le(s, SEC_TAG_KEYSIG); /* 0x0008 */
out_uint16_le(s, 72); /* len */
out_uint8a(s, self->pub_sig, 64); /* pub sig */
out_uint8s(s, 8); /* pad */
}
else if (self->rsa_key_bytes == 0) /* no security */
{
g_writeln("xrdp_sec_out_mcs_data: using no security");
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 12); /* len is 12 */
out_uint32_le(s, self->crypt_method);
out_uint32_le(s, self->crypt_level);
}
else
{
g_writeln("xrdp_sec_out_mcs_data: error");
}
/* end certificate */
s_mark_end(s);
gcc_size = (int)(s->end - ud_ptr) | 0x8000;
gcc_size_ptr[0] = gcc_size >> 8;
gcc_size_ptr[1] = gcc_size;
return 0;
}
/*****************************************************************************/
/* returns error */
static int APP_CC
@ -737,9 +874,11 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
DEBUG((" in xrdp_mcs_send_connect_response"));
make_stream(s);
init_stream(s, 8192);
data_len = self->server_mcs_data->end - self->server_mcs_data->data;
data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data);
xrdp_iso_init(self->iso_layer, s);
xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38);
//TODO: we should calculate the whole length include MCS_CONNECT_RESPONSE
xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE,
data_len > 0x80 ? data_len + 38 : data_len + 36);
xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1);
out_uint8(s, 0);
xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1);
@ -767,13 +906,9 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
int APP_CC
xrdp_mcs_incoming(struct xrdp_mcs *self)
{
int i;
DEBUG((" in xrdp_mcs_incoming"));
if (xrdp_iso_incoming(self->iso_layer) != 0)
{
return 1;
}
if (xrdp_mcs_recv_connect_initial(self) != 0)
{
return 1;
@ -785,8 +920,7 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)
return 1;
}
/* in xrdp_sec.c */
if (xrdp_sec_out_mcs_data(self->sec_layer) != 0)
if (xrdp_mcs_out_gcc_data(self->sec_layer) != 0)
{
return 1;
}
@ -811,25 +945,18 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)
return 1;
}
if (xrdp_mcs_recv_cjrq(self) != 0)
{
return 1;
}
if (xrdp_mcs_send_cjcf(self, self->userid,
self->userid + MCS_USERCHANNEL_BASE) != 0)
{
return 1;
}
if (xrdp_mcs_recv_cjrq(self) != 0)
for (i = 0; i < self->channel_list->count + 2; i++)
{
return 1;
}
if (xrdp_mcs_recv_cjrq(self) != 0)
{
return 1;
}
if (xrdp_mcs_send_cjcf(self, self->userid, MCS_GLOBAL_CHANNEL) != 0)
{
return 1;
if (xrdp_mcs_send_cjcf(self, self->userid,
self->userid + MCS_USERCHANNEL_BASE + i) != 0)
{
return 1;
}
}
DEBUG((" out xrdp_mcs_incoming"));
@ -895,7 +1022,7 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
if (len > 8192 * 2)
{
g_writeln("error in xrdp_mcs_send, size too bog, its %d", len);
g_writeln("error in xrdp_mcs_send, size too big, its %d", len);
}
//if (len > max_len)
@ -958,6 +1085,7 @@ close_rdp_socket(struct xrdp_mcs *self)
{
if (self->iso_layer->trans != 0)
{
trans_shutdown_tls_mode(self->iso_layer->trans);
g_tcp_close(self->iso_layer->trans->sck);
self->iso_layer->trans->sck = 0 ;
g_writeln("xrdp_mcs_disconnect - socket closed");

@ -456,7 +456,7 @@ mppc_enc_new(int protocol_type)
return 0;
}
enc->first_pkt = 1;
enc->flagsHold = PACKET_AT_FRONT;
enc->historyBuffer = (char *) g_malloc(enc->buf_len, 1);
if (enc->historyBuffer == 0)
@ -574,20 +574,13 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
g_memset(outputBuffer, 0, len);
enc->flags = PACKET_COMPR_TYPE_64K;
if (enc->first_pkt)
{
enc->first_pkt = 0;
enc->flagsHold |= PACKET_AT_FRONT;
}
if ((enc->historyOffset + len) >= enc->buf_len)
if ((enc->historyOffset + len) >= enc->buf_len - 3)
{
/* historyBuffer cannot hold srcData - rewind it */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
g_memset(enc->historyBuffer, 0, enc->buf_len); // added
enc->first_pkt = 0;
enc->flagsHold |= PACKET_AT_FRONT;
enc->flagsHold |= PACKET_AT_FRONT | PACKET_FLUSHED;
}
/* point to next free byte in historyBuffer */
@ -602,7 +595,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
ctr = copy_offset = lom = 0;
/* if we are at start of history buffer, do not attempt to compress */
/* first 2 bytes,because minimum LoM is 3 */
/* first 2 bytes, because minimum LoM is 3 */
if (historyOffset == 0)
{
/* encode first two bytes as literals */
@ -970,40 +963,6 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
ctr++;
}
/* if bits_left == 8, opb_index has already been incremented */
if ((bits_left == 8) && (opb_index > len))
{
/* compressed data longer than uncompressed data */
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
g_memcpy(enc->outputBuffer, srcData, len);
enc->bytes_in_opb = len;
enc->flags = 0x81;
return 1;
}
else if (opb_index + 1 > len)
{
/* compressed data longer than uncompressed data */
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
g_memcpy(enc->outputBuffer, srcData, len);
enc->bytes_in_opb = len;
enc->flags = 0x81;
return 1;
}
/* if bits_left != 8, increment opb_index, which is zero indexed */
if (bits_left != 8)
{
@ -1012,24 +971,21 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
if (opb_index > len)
{
/* compressed data longer than uncompressed data */
/* give up */
enc->historyOffset = 0;
g_memset(hash_table, 0, enc->buf_len * 2);
g_memset(enc->historyBuffer, 0, enc->buf_len);
enc->flagsHold |= PACKET_FLUSHED;
enc->first_pkt = 1;
g_memcpy(enc->outputBuffer, srcData, len);
enc->bytes_in_opb = len;
enc->flags = 0x81;
return 1;
enc->flagsHold |= PACKET_AT_FRONT | PACKET_FLUSHED;
return 0;
}
enc->flags |= PACKET_COMPRESSED;
enc->bytes_in_opb = opb_index;
enc->flags |= enc->flagsHold;
enc->flagsHold = 0;
DLOG(("\n"));
//g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb);

@ -34,6 +34,8 @@
} \
}
#define MAX_ORDERS_SIZE (16 * 1024 - 256)
/*****************************************************************************/
struct xrdp_orders *APP_CC
xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
@ -44,7 +46,7 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
self->session = session;
self->rdp_layer = rdp_layer;
make_stream(self->out_s);
init_stream(self->out_s, 16384);
init_stream(self->out_s, 32 * 1024);
self->orders_state.clip_right = 1; /* silly rdp right clip */
self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */
self->jpeg_han = xrdp_jpeg_init();
@ -53,6 +55,8 @@ xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer)
{
self->rfx_min_pixel = 64 * 32;
}
make_stream(self->s);
make_stream(self->temp_s);
return self;
}
@ -64,9 +68,10 @@ xrdp_orders_delete(struct xrdp_orders *self)
{
return;
}
xrdp_jpeg_deinit(self->jpeg_han);
free_stream(self->out_s);
free_stream(self->s);
free_stream(self->temp_s);
g_free(self->orders_state.text_data);
g_free(self);
}
@ -81,7 +86,6 @@ xrdp_orders_reset(struct xrdp_orders *self)
{
return 1;
}
g_free(self->orders_state.text_data);
g_memset(&(self->orders_state), 0, sizeof(self->orders_state));
self->order_count_ptr = 0;
@ -98,24 +102,33 @@ int APP_CC
xrdp_orders_init(struct xrdp_orders *self)
{
self->order_level++;
if (self->order_level == 1)
{
self->order_count = 0;
/* is this big enough */
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
if (self->rdp_layer->client_info.use_fast_path & 1)
{
return 1;
LLOGLN(10, ("xrdp_orders_init: fastpath"));
if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0)
{
return 1;
}
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
}
else
{
LLOGLN(10, ("xrdp_orders_init: slowpath"));
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
{
return 1;
}
out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
out_uint8s(self->out_s, 2); /* pad */
}
out_uint16_le(self->out_s, RDP_UPDATE_ORDERS);
out_uint8s(self->out_s, 2); /* pad */
self->order_count_ptr = self->out_s->p;
out_uint8s(self->out_s, 2); /* number of orders, set later */
out_uint8s(self->out_s, 2); /* pad */
}
return 0;
}
@ -127,11 +140,9 @@ xrdp_orders_send(struct xrdp_orders *self)
int rv;
rv = 0;
if (self->order_level > 0)
{
self->order_level--;
if ((self->order_level == 0) && (self->order_count > 0))
{
s_mark_end(self->out_s);
@ -139,15 +150,24 @@ xrdp_orders_send(struct xrdp_orders *self)
self->order_count_ptr[0] = self->order_count;
self->order_count_ptr[1] = self->order_count >> 8;
self->order_count = 0;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
if (self->rdp_layer->client_info.use_fast_path & 1)
{
if (xrdp_rdp_send_fastpath(self->rdp_layer,
self->out_s, 0) != 0)
{
rv = 1;
}
}
else
{
rv = 1;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
rv = 1;
}
}
}
}
return rv;
}
@ -160,21 +180,29 @@ xrdp_orders_force_send(struct xrdp_orders *self)
{
return 1;
}
if ((self->order_level > 0) && (self->order_count > 0))
{
s_mark_end(self->out_s);
DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count));
self->order_count_ptr[0] = self->order_count;
self->order_count_ptr[1] = self->order_count >> 8;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
if (self->rdp_layer->client_info.use_fast_path & 1)
{
return 1;
if (xrdp_rdp_send_fastpath(self->rdp_layer,
self->out_s, FASTPATH_UPDATETYPE_ORDERS) != 0)
{
return 1;
}
}
else
{
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
return 1;
}
}
}
self->order_count = 0;
self->order_level = 0;
return 0;
@ -190,14 +218,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
int size;
int max_packet_size;
if (self->rdp_layer->client_info.bpp == 8)
{
max_packet_size = 8000;
}
else
{
max_packet_size = 16000;
}
max_packet_size = MAX_ORDERS_SIZE;
if (self->order_level < 1)
{
@ -2304,19 +2325,26 @@ xrdp_orders_send_bitmap(struct xrdp_orders *self,
e = 4 - e;
}
make_stream(s);
init_stream(s, 16384);
make_stream(temp_s);
init_stream(temp_s, 16384);
s = self->s;
init_stream(s, 16384 * 2);
temp_s = self->temp_s;
init_stream(temp_s, 16384 * 2);
p = s->p;
i = height;
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
bpp, 16384,
i - 1, temp_s, e, 0x10);
}
else
{
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
}
if (lines_sending != height)
{
free_stream(s);
free_stream(temp_s);
g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \
height(%d)", lines_sending, height);
return 1;
@ -2364,8 +2392,6 @@ height(%d)", lines_sending, height);
}
out_uint8a(self->out_s, s->data, bufsize);
free_stream(s);
free_stream(temp_s);
return 0;
}
@ -2564,16 +2590,17 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
e = 4 - e;
}
make_stream(s);
init_stream(s, 16384);
make_stream(temp_s);
init_stream(temp_s, 16384);
s = self->s;
init_stream(s, 16384 * 2);
temp_s = self->temp_s;
init_stream(temp_s, 16384 * 2);
p = s->p;
i = height;
if (bpp > 24)
{
lines_sending = xrdp_bitmap32_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
lines_sending = xrdp_bitmap32_compress(data, width, height, s,
bpp, 16384,
i - 1, temp_s, e, 0x10);
}
else
{
@ -2583,8 +2610,6 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
if (lines_sending != height)
{
free_stream(s);
free_stream(temp_s);
g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \
height(%d)", lines_sending, height);
return 1;
@ -2613,8 +2638,6 @@ height(%d)", lines_sending, height);
i = cache_idx & 0xff;
out_uint8(self->out_s, i);
out_uint8a(self->out_s, s->data, bufsize);
free_stream(s);
free_stream(temp_s);
return 0;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2012
* Copyright (C) Jay Sorg 2012-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,31 +20,31 @@
#define _XRDP_ORDERS_RAIL_H
int APP_CC
xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id);
xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id);
int APP_CC
xrdp_orders_send_window_cached_icon(struct xrdp_orders* self,
xrdp_orders_send_window_cached_icon(struct xrdp_orders *self,
int window_id, int cache_entry,
int cache_id, int flags);
int APP_CC
xrdp_orders_send_window_icon(struct xrdp_orders* self,
xrdp_orders_send_window_icon(struct xrdp_orders *self,
int window_id, int cache_entry, int cache_id,
struct rail_icon_info* icon_info,
struct rail_icon_info *icon_info,
int flags);
int APP_CC
xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id,
struct rail_window_state_order* window_state,
xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id,
struct rail_window_state_order *window_state,
int flags);
int APP_CC
xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id,
xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id,
int notify_id);
int APP_CC
xrdp_orders_send_notify_new_update(struct xrdp_orders* self,
xrdp_orders_send_notify_new_update(struct xrdp_orders *self,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
struct rail_notify_state_order *notify_state,
int flags);
int APP_CC
xrdp_orders_send_monitored_desktop(struct xrdp_orders* self,
struct rail_monitored_desktop_order* mdo,
xrdp_orders_send_monitored_desktop(struct xrdp_orders *self,
struct rail_monitored_desktop_order *mdo,
int flags);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -275,11 +275,13 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
case 107: /* wheel up */
flags = PTR_FLAGS_WHEEL | 0x0078;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
case 108:
break;
case 109: /* wheel down */
flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
break;
case 110:
break;
case 200:
@ -296,8 +298,8 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2,
size = (int)param2;
data = (char *)param3;
total_size = (int)param4;
LLOGLN(12, ("lxrdp_event: client to server flags %d", flags));
LLOGLN(12, ("lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags));
if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels))
{
LLOGLN(0, ("lxrdp_event: error chanid %d", chanid));
@ -491,7 +493,7 @@ lfreerdp_begin_paint(rdpContext *context)
{
struct mod *mod;
LLOGLN(10, ("lfreerdp_begin_paint:"));
LLOGLN(12, ("lfreerdp_begin_paint:"));
mod = ((struct mod_context *)context)->modi;
mod->server_begin_update(mod);
}
@ -502,7 +504,7 @@ lfreerdp_end_paint(rdpContext *context)
{
struct mod *mod;
LLOGLN(10, ("lfreerdp_end_paint:"));
LLOGLN(12, ("lfreerdp_end_paint:"));
mod = ((struct mod_context *)context)->modi;
mod->server_end_update(mod);
}
@ -517,7 +519,7 @@ lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds)
int cx;
int cy;
LLOGLN(10, ("lfreerdp_set_bounds: %p", bounds));
LLOGLN(12, ("lfreerdp_set_bounds: %p", bounds));
mod = ((struct mod_context *)context)->modi;
if (bounds != 0)
@ -734,7 +736,7 @@ lfreerdp_mem_blt(rdpContext *context, MEMBLT_ORDER *memblt)
struct bitmap_item *bi;
mod = ((struct mod_context *)context)->modi;
LLOGLN(10, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d",
LLOGLN(12, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d",
memblt->cacheId, memblt->cacheIndex));
id = memblt->cacheId;
@ -1353,7 +1355,7 @@ static void DEFAULT_CC lfreerdp_syncronize(rdpContext* context)
{
struct mod *mod;
mod = ((struct mod_context *)context)->modi;
LLOGLN(0, ("lfreerdp_synchronize received - not handled"));
LLOGLN(12, ("lfreerdp_synchronize received - not handled"));
}
/******************************************************************************/
@ -1378,8 +1380,8 @@ lfreerdp_pre_connect(freerdp *instance)
while (error == 0)
{
num_chans++;
LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], flags [0x%8.8x]",
ch_name, ch_flags));
LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], id [%d], flags [0x%8.8x]",
ch_name, index, ch_flags));
dst_ch_name = instance->settings->channels[index].name;
g_memset(dst_ch_name, 0, 8);
g_snprintf(dst_ch_name, 8, "%s", ch_name);
@ -1408,24 +1410,25 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->order_support[NEG_MEM3BLT_INDEX] = 0;
instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = 0;
instance->settings->bitmapCacheV2NumCells = 3; // 5;
instance->settings->bitmapCacheV2CellInfo[0].numEntries = 0x78; // 600;
instance->settings->bitmapCacheV2CellInfo[0].numEntries = 600; // 0x78;
instance->settings->bitmapCacheV2CellInfo[0].persistent = 0;
instance->settings->bitmapCacheV2CellInfo[1].numEntries = 0x78; // 600;
instance->settings->bitmapCacheV2CellInfo[1].numEntries = 600; //0x78; // 600;
instance->settings->bitmapCacheV2CellInfo[1].persistent = 0;
instance->settings->bitmapCacheV2CellInfo[2].numEntries = 0x150; // 2048;
instance->settings->bitmapCacheV2CellInfo[2].numEntries = 2048; //0x150; // 2048;
instance->settings->bitmapCacheV2CellInfo[2].persistent = 0;
instance->settings->bitmapCacheV2CellInfo[3].numEntries = 0; // 4096;
instance->settings->bitmapCacheV2CellInfo[3].numEntries = 4096; // 4096;
instance->settings->bitmapCacheV2CellInfo[3].persistent = 0;
instance->settings->bitmapCacheV2CellInfo[4].numEntries = 0; // 2048;
instance->settings->bitmapCacheV2CellInfo[4].numEntries = 2048; // 2048;
instance->settings->bitmapCacheV2CellInfo[4].persistent = 0;
// instance->settings->BitmapCacheV3Enabled = FALSE;
instance->settings->bitmap_cache_v3 = 1;
instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = 0;
instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = 0;
instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = 0;
instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = 0;
instance->settings->order_support[NEG_POLYLINE_INDEX] = 0;
instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password);
@ -1436,6 +1439,10 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->rail_langbar_supported = 1;
instance->settings->workarea = 1;
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
instance->settings->num_icon_caches = mod->client_info.wnd_num_icon_caches;
instance->settings->num_icon_cache_entries = mod->client_info.wnd_num_icon_cache_entries;
}
else
{
@ -1448,8 +1455,16 @@ lfreerdp_pre_connect(freerdp *instance)
instance->settings->compression = 0;
instance->settings->ignore_certificate = 1;
// here
//instance->settings->RdpVersion = 4;
// Multi Monitor Settings
instance->settings->num_monitors = mod->client_info.monitorCount;
for (index = 0; index < mod->client_info.monitorCount; index++)
{
instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
}
instance->update->BeginPaint = lfreerdp_begin_paint;
instance->update->EndPaint = lfreerdp_end_paint;
@ -1648,21 +1663,21 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
rnso.version = notify_icon_state->version;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
{
rnso.tool_tip = freerdp_uniconv_in(uniconv,
notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
rnso.infotip.flags = notify_icon_state->infoTip.flags;
rnso.infotip.text = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.text.string,
notify_icon_state->infoTip.text.length);
rnso.infotip.title = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.title.string,
notify_icon_state->infoTip.title.length);
}
{
rnso.tool_tip = freerdp_uniconv_in(uniconv,
notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
}
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
{
rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
rnso.infotip.flags = notify_icon_state->infoTip.flags;
rnso.infotip.text = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.text.string,
notify_icon_state->infoTip.text.length);
rnso.infotip.title = freerdp_uniconv_in(uniconv,
notify_icon_state->infoTip.title.string,
notify_icon_state->infoTip.title.length);
}
rnso.state = notify_icon_state->state;
rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry;
@ -1815,7 +1830,7 @@ lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data,
if (lchid >= 0)
{
LLOGLN(10, ("lfreerdp_receive_channel_data: server to client"));
LLOGLN(10, ("lfreerdp_receive_channel_data: server to client, chanid: %d", lchid));
error = mod->server_send_to_channel(mod, lchid, (char *)data, size,
total_size, flags);

@ -164,6 +164,7 @@ bitmap_decompress1(char *output, int width, int height, char *input, int size)
break;
case 8: /* Bicolor */
color1 = CVAL(input);
/* fall through is intentional */
case 3: /* Color */
color2 = CVAL(input);
break;
@ -435,6 +436,7 @@ bitmap_decompress2(char *output, int width, int height, char *input, int size)
case 8: /* Bicolor */
color1[EIK0] = CVAL(input);
color1[EIK1] = CVAL(input);
/* fall through is intentional */
case 3: /* Color */
color2[EIK0] = CVAL(input);
color2[EIK1] = CVAL(input);
@ -752,6 +754,7 @@ bitmap_decompress3(char *output, int width, int height, char *input, int size)
color1[0] = CVAL(input);
color1[1] = CVAL(input);
color1[2] = CVAL(input);
/* fall through is intentional */
case 3: /* Color */
color2[0] = CVAL(input);
color2[1] = CVAL(input);

@ -174,6 +174,8 @@ rdp_lic_process_demand(struct rdp_lic *self, struct stream *s)
the security of licence negotiation isn't exactly paramount. */
g_memset(null_data, 0, sizeof(null_data));
rdp_lic_generate_keys(self, null_data, server_random, null_data);
#if 0
licence_size = 0; /* todo load_licence(&licence_data); */
if (licence_size > 0)
@ -192,6 +194,7 @@ rdp_lic_process_demand(struct rdp_lic *self, struct stream *s)
g_free(licence_data);
return;
}
#endif
rdp_lic_send_request(self, null_data, null_data,
self->sec_layer->rdp_layer->mod->username,

@ -19,6 +19,7 @@
*/
#include "rdp.h"
#include "common/log.h"
/*****************************************************************************/
struct rdp_mcs *APP_CC
@ -598,7 +599,8 @@ failed"));
int APP_CC
rdp_mcs_init(struct rdp_mcs *self, struct stream *s)
{
rdp_iso_init(self->iso_layer, s);
if (rdp_iso_init(self->iso_layer, s))
log_message(LOG_LEVEL_ERROR, "rdp_mcs.c: rdp_iso_init() failed");
s_push_layer(s, mcs_hdr, 8);
return 0;
}

@ -427,6 +427,12 @@ rdp_rdp_process_color_pointer_pdu(struct rdp_rdp *self, struct stream *s)
return 1;
}
/* there are only 32 cursors */
if (cache_idx > 31)
{
return 1;
}
cursor = self->cursors + cache_idx;
in_uint16_le(s, cursor->x);
in_uint16_le(s, cursor->y);
@ -457,7 +463,7 @@ rdp_rdp_process_cached_pointer_pdu(struct rdp_rdp *self, struct stream *s)
in_uint16_le(s, cache_idx);
if (cache_idx >= sizeof(self->cursors) / sizeof(cursor))
if (cache_idx > 31)
{
return 1;
}
@ -1164,6 +1170,9 @@ rdp_rec_check_file(struct rdp_rdp *self)
}
self->rec_fd = g_file_open(file_name);
if (self->rec_fd < 0)
return 1;
make_stream(s);
init_stream(s, 8192);
out_uint8a(s, "XRDPREC1", 8);

@ -157,7 +157,10 @@ int APP_CC
rdp_tcp_connect(struct rdp_tcp *self, char *ip, char *port)
{
DEBUG((" in rdp_tcp_connect ip %s port %s", ip, port));
self->sck = g_tcp_socket();
if (self->sck < 0)
return 1;
if (g_tcp_connect(self->sck, ip, port) == 0)
{

@ -16,21 +16,11 @@ EXTRA_INCLUDES =
EXTRA_LIBS =
EXTRA_FLAGS =
if XRDP_SIMPLESOUND
EXTRA_DEFINES += -DXRDP_SIMPLESOUND
EXTRA_LIBS += -lpthread -lpulse -lpulse-simple
endif
if XRDP_FUSE
EXTRA_DEFINES += -DXRDP_FUSE
EXTRA_LIBS += -lfuse
endif
if XRDP_LOAD_PULSE_MODULES
EXTRA_DEFINES += -DXRDP_LOAD_PULSE_MODULES
EXTRA_LIBS += -lpulse
endif
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \

@ -38,7 +38,7 @@
static struct trans *g_lis_trans = 0;
static struct trans *g_con_trans = 0;
static struct trans *g_api_lis_trans = 0;
static struct trans *g_api_con_trans = 0;
static struct list *g_api_con_trans_list = 0; /* list of apps using api functions */
static struct chan_item g_chan_items[32];
static int g_num_chan_items = 0;
static int g_cliprdr_index = -1;
@ -608,7 +608,10 @@ process_message_channel_data(struct stream *s)
int rv = 0;
int length = 0;
int total_length = 0;
int index;
struct stream *ls;
struct trans *ltran;
struct xrdp_api_data *api_data;
in_uint16_le(s, chan_id);
in_uint16_le(s, chan_flags);
@ -641,29 +644,36 @@ process_message_channel_data(struct stream *s)
{
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
}
else if ((g_api_con_trans != 0) &&
(chan_id == ((struct xrdp_api_data *)
(g_api_con_trans->callback_data))->chan_id))
else if (g_api_con_trans_list != 0)
{
LOG(10, ("process_message_channel_data length %d total_length %d "
"chan_flags 0x%8.8x", length, total_length, chan_flags));
ls = g_api_con_trans->out_s;
if (chan_flags & 1) /* first */
{
init_stream(ls, total_length);
}
out_uint8a(ls, s->p, length);
if (chan_flags & 2) /* last */
for (index = 0; index < g_api_con_trans_list->count; index++)
{
s_mark_end(ls);
rv = trans_force_write(g_api_con_trans);
ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
if (ltran != 0)
{
api_data = (struct xrdp_api_data *) (ltran->callback_data);
if (api_data != 0)
{
if (api_data->chan_id == chan_id)
{
ls = ltran->out_s;
if (chan_flags & 1) /* first */
{
init_stream(ls, total_length);
}
out_uint8a(ls, s->p, length);
if (chan_flags & 2) /* last */
{
s_mark_end(ls);
rv = trans_force_write(ltran);
}
break;
}
}
}
}
}
}
return rv;
}
@ -796,9 +806,12 @@ my_api_trans_data_in(struct trans *trans)
return 0;
}
if (trans != g_api_con_trans)
if (g_api_con_trans_list != 0)
{
return 1;
if (list_index_of(g_api_con_trans_list, (tintptr) trans) == -1)
{
return 1;
}
}
LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:"));
@ -812,7 +825,8 @@ my_api_trans_data_in(struct trans *trans)
in_uint8s(s, 12);
in_uint32_le(s, bytes_read);
init_stream(s, bytes_read);
trans_force_read(trans, bytes_read);
if (trans_force_read(trans, bytes_read))
log_message(LOG_LEVEL_ERROR, "chansrv.c: error reading from transport");
}
else if (g_tcp_select(trans->sck, 0) & 1)
{
@ -932,6 +946,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
LOG(0, ("my_api_trans_conn_in: trans_force_read failed"));
trans_delete(new_trans);
return 1;
}
s->end = s->data;
@ -987,10 +1002,13 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
new_trans->callback_data = ad;
trans_delete(g_api_con_trans);
g_api_con_trans = new_trans;
g_api_con_trans->trans_data_in = my_api_trans_data_in;
g_api_con_trans->header_size = 0;
if (g_api_con_trans_list == 0)
{
g_api_con_trans_list = list_create();
}
new_trans->trans_data_in = my_api_trans_data_in;
new_trans->header_size = 0;
list_add_item(g_api_con_trans_list, (tintptr) new_trans);
return 0;
}
@ -1011,8 +1029,7 @@ setup_listen(void)
{
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
g_lis_trans->is_term = g_is_term;
g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d",
7200 + g_display_num);
g_snprintf(port, 255, XRDP_CHANSRV_STR, g_display_num);
}
else
{
@ -1043,7 +1060,7 @@ setup_api_listen(void)
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
g_api_lis_trans->is_term = g_is_term;
g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num);
g_snprintf(port, 255, CHANSRV_API_STR, g_display_num);
g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
error = trans_listen(g_api_lis_trans, port);
@ -1067,7 +1084,9 @@ channel_thread_loop(void *in_val)
int num_wobjs;
int timeout;
int error;
int index;
THREAD_RV rv;
struct trans *ltran;
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
rv = 0;
@ -1137,19 +1156,20 @@ channel_thread_loop(void *in_val)
}
}
LOG(10, ("0 %p", g_api_con_trans));
if (g_api_con_trans != 0)
if (g_api_con_trans_list != 0)
{
LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));
if (trans_check_wait_objs(g_api_con_trans) != 0)
for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
{
LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
"or disconnected"));
g_free(g_api_con_trans->callback_data);
trans_delete(g_api_con_trans);
g_api_con_trans = 0;
ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
if (ltran != 0)
{
if (trans_check_wait_objs(ltran) != 0)
{
list_remove_item(g_api_con_trans_list, index);
g_free(ltran->callback_data);
trans_delete(ltran);
}
}
}
}
@ -1166,7 +1186,19 @@ channel_thread_loop(void *in_val)
trans_get_wait_objs_rw(g_con_trans, objs, &num_objs,
wobjs, &num_wobjs);
trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
if (g_api_con_trans_list != 0)
{
for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
{
ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
if (ltran != 0)
{
trans_get_wait_objs(ltran, objs, &num_objs);
}
}
}
xcommon_get_wait_objs(objs, &num_objs, &timeout);
sound_get_wait_objs(objs, &num_objs, &timeout);
dev_redir_get_wait_objs(objs, &num_objs, &timeout);
@ -1181,8 +1213,20 @@ channel_thread_loop(void *in_val)
g_con_trans = 0;
trans_delete(g_api_lis_trans);
g_api_lis_trans = 0;
trans_delete(g_api_con_trans);
g_api_con_trans = 0;
if (g_api_con_trans_list != 0)
{
for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
{
ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
if (ltran != 0)
{
list_remove_item(g_api_con_trans_list, index);
g_free(ltran->callback_data);
trans_delete(ltran);
}
}
list_delete(g_api_con_trans_list);
}
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
g_set_wait_obj(g_thread_done_event);
return rv;
@ -1599,11 +1643,6 @@ remove_struct_with_chan_id(tui32 dvc_chan_id)
{
int i;
if (dvc_chan_id < 0)
{
return -1;
}
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)

@ -39,6 +39,8 @@
//#define USE_SYNC_FLAG
static char g_fuse_mount_name[256] = "xrdp_client";
/* FUSE mount point */
char g_fuse_root_path[256] = "";
char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
@ -71,7 +73,7 @@ int xfuse_create_share(tui32 device_id, char *dirname) { r
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {}
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {}
@ -369,6 +371,37 @@ int clipboard_request_file_data(int stream_id, int lindex, int offset,
static void xfuse_mark_as_stale(int pinode);
static void xfuse_delete_stale_entries(int pinode);
/*****************************************************************************/
int APP_CC
load_fuse_config(void)
{
int index;
char cfg_file[256];
struct list *items;
struct list *values;
char *item;
char *value;
items = list_create();
items->auto_free = 1;
values = list_create();
values->auto_free = 1;
g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
file_by_name_read_section(cfg_file, "Chansrv", items, values);
for (index = 0; index < items->count; index++)
{
item = (char *)list_get_item(items, index);
value = (char *)list_get_item(values, index);
if (g_strcasecmp(item, "FuseMountName") == 0)
{
g_strncpy(g_fuse_mount_name, value, 255);
}
}
list_delete(items);
list_delete(values);
return 0;
}
/*****************************************************************************
** **
** public functions - can be called from any code path **
@ -381,7 +414,8 @@ static void xfuse_delete_stale_entries(int pinode);
* @return 0 on success, -1 on failure
*****************************************************************************/
int xfuse_init()
int APP_CC
xfuse_init(void)
{
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
@ -398,8 +432,10 @@ int xfuse_init()
return -1;
}
/* define FUSE mount point to ~/xrdp_client */
g_snprintf(g_fuse_root_path, 255, "%s/xrdp_client", g_getenv("HOME"));
load_fuse_config();
/* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */
g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_fuse_mount_name);
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
/* if FUSE mount point does not exist, create it */
@ -460,7 +496,8 @@ int xfuse_init()
* @return 0 on success, -1 on failure
*****************************************************************************/
int xfuse_deinit()
int APP_CC
xfuse_deinit(void)
{
xfuse_deinit_xrdp_fs();
fifo_deinit(&g_fifo_opendir);
@ -1385,7 +1422,7 @@ static void xfuse_update_xrdpfs_size()
* Add a file or directory to xrdp file system
*****************************************************************************/
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
XRDP_INODE *xip = NULL;
@ -1393,13 +1430,14 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
if ((fip == NULL) || (xinode == NULL))
{
log_error("fip or xinode are NULL");
return;
return -1;
}
if (!xfuse_is_inode_valid(fip->inode))
{
log_error("inode %d is not valid", fip->inode);
return;
g_free(xinode);
return -1;
}
log_debug("parent_inode=%d name=%s", fip->inode, xinode->name);
@ -1407,8 +1445,8 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
/* if filename is . or .. don't add it */
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
{
free(xinode);
return;
g_free(xinode);
return -1;
}
xfuse_dump_fs();
@ -1417,9 +1455,9 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
fip->inode, xinode->name);
free(xinode);
g_free(xinode);
xip->stale = 0;
return;
return -1;
}
xinode->parent_inode = fip->inode;
@ -1436,6 +1474,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
xfuse_update_xrdpfs_size();
xfuse_dump_fs();
return 0;
}
/**
@ -1742,12 +1781,15 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
new_xinode = xfuse_get_inode_from_pinode_name(fip->new_inode,
fip->new_name);
if (new_xinode->mode & S_IFREG)
xfuse_delete_file_with_xinode(new_xinode);
else
xfuse_delete_dir_with_xinode(new_xinode);
if (new_xinode)
{
if (new_xinode->mode & S_IFREG)
xfuse_delete_file_with_xinode(new_xinode);
else
xfuse_delete_dir_with_xinode(new_xinode);
new_xinode = NULL;
new_xinode = NULL;
}
}
old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
@ -1759,7 +1801,8 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
}
old_xinode->parent_inode = fip->new_inode;
strcpy(old_xinode->name, fip->new_name);
strncpy(old_xinode->name, fip->new_name, 1023);
old_xinode->name[1023] = 0;
if (fip->inode != fip->new_inode)
{
@ -1987,7 +2030,7 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
return;
}
di = (struct dir_info *) fi->fh;
di = (struct dir_info *) (tintptr) (fi->fh);
if (di == NULL)
{
/* something seriously wrong somewhere! */
@ -2142,7 +2185,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
}
strcat(full_path, "/");
strcat(full_path, name);
strncat(full_path, name, sizeof(full_path) - strlen(full_path));
if (xinode->is_loc_resource)
{
@ -2583,7 +2626,6 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
fip, fip->fi, fip->fi->fh);
FileId = handle->FileId;
free(handle);
fip->fi->fh = 0;
xinode->close_in_progress = 1;
@ -2592,6 +2634,8 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
log_error("failed to send devredir_close_file() cmd");
fuse_reply_err(req, EREMOTEIO);
}
free(handle);
}
/**

@ -34,7 +34,7 @@ struct xrdp_inode
time_t atime; /* Time of last access. */
time_t mtime; /* Time of last modification. */
time_t ctime; /* Time of last status change. */
char name[256]; /* Dir or filename */
char name[1024]; /* Dir or filename */
tui32 device_id; /* for file system redirection */
char is_synced; /* dir struct has been read from */
/* remote device, done just once */
@ -57,7 +57,7 @@ int xfuse_file_contents_size(int stream_id, int file_size);
int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex);
/* functions that are invoked from devredir */
void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length);

@ -1048,8 +1048,11 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
clip_msg_len);
g_formatIds[g_num_formatIds] = formatId;
g_num_formatIds++;
if (g_num_formatIds <= 15)
{
g_formatIds[g_num_formatIds] = formatId;
g_num_formatIds++;
}
if (g_num_formatIds > 15)
{
log_debug("clipboard_process_format_announce: max formats");

@ -446,7 +446,13 @@ clipboard_send_file_data(int streamId, int lindex,
full_fn);
return 1;
}
g_file_seek(fd, nPositionLow);
if (g_file_seek(fd, nPositionLow) < 0)
{
log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
"in file: %s\n", full_fn);
g_file_close(fd);
return 1;
}
make_stream(s);
init_stream(s, cbRequested + 64);
size = g_file_read(fd, s->data + 12, cbRequested);

@ -118,7 +118,7 @@ dev_redir_init(void)
} u;
/* get a random number that will act as a unique clientID */
if ((fd = open("/dev/urandom", O_RDONLY)))
if ((fd = open("/dev/urandom", O_RDONLY)) != -1)
{
if (read(fd, u.buf, 4) != 4)
{
@ -790,10 +790,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
{
log_error("fuse_data is NULL");
xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
else
{
xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
break;
case CID_WRITE:
@ -802,10 +806,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
{
log_error("fuse_data is NULL");
xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
else
{
xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
devredir_irp_delete(irp);
}
break;
case CID_CLOSE:
@ -879,7 +887,7 @@ dev_redir_proc_query_dir_response(IRP *irp,
tui32 IoStatus)
{
FUSE_DATA *fuse_data = NULL;
XRDP_INODE *xinode = NULL;
XRDP_INODE *xinode;
tui32 Length;
tui32 NextEntryOffset;
@ -1017,7 +1025,8 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_CREATE_DIR_REQ;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
@ -1060,7 +1069,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
if (type & OP_RENAME_FILE)
{
irp->completion_type = CID_RENAME_FILE;
strcpy(irp->gen_buf, gen_buf);
strncpy(irp->gen_buf, gen_buf, 1023);
}
else
{
@ -1069,7 +1078,8 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
irp->CompletionId = g_completion_id++;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
if (mode & O_CREAT)
@ -1174,7 +1184,8 @@ devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_RMDIR_OR_FILE;
irp->DeviceId = device_id;
strcpy(irp->pathname, path);
strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
//DesiredAccess = DA_DELETE | DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE;
@ -1216,6 +1227,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
@ -1224,6 +1236,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_read_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
new_irp->FileId = 0;
@ -1268,6 +1281,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_write_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
@ -1276,6 +1290,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_write_file(fusep, NULL, 0);
xstream_free(s);
return -1;
}
new_irp->FileId = 0;

@ -15,8 +15,13 @@
typedef unsigned char BYTE;
typedef BYTE *LPBYTE;
typedef unsigned int LONG;
#ifdef __APPLE__
typedef int LONG;
typedef unsigned int DWORD;
#else
typedef long LONG;
typedef unsigned long DWORD;
#endif
typedef DWORD *LPDWORD;
typedef const void *LPCVOID;
typedef const char *LPCSTR;
@ -59,6 +64,8 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
#define LLOG_LEVEL 5
#define LLOGLN(_level, _args) \
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
#define LHEXDUMP(_level, _args) \
do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0)
#define SCARD_ESTABLISH_CONTEXT 0x01
#define SCARD_RELEASE_CONTEXT 0x02
@ -102,6 +109,50 @@ static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
/* for pcsc_stringify_error */
static char g_error_str[512];
/*****************************************************************************/
/* produce a hex dump */
static void
lhexdump(void *p, int len)
{
unsigned char *line;
int i;
int thisline;
int offset;
line = (unsigned char *)p;
offset = 0;
while (offset < len)
{
printf("%04x ", offset);
thisline = len - offset;
if (thisline > 16)
{
thisline = 16;
}
for (i = 0; i < thisline; i++)
{
printf("%02x ", line[i]);
}
for (; i < 16; i++)
{
printf(" ");
}
for (i = 0; i < thisline; i++)
{
printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
}
printf("\n");
offset += thisline;
line += thisline;
}
}
/*****************************************************************************/
static int
get_display_num_from_display(const char *display_text)
@ -156,7 +207,7 @@ get_display_num_from_display(const char *display_text)
host[host_index] = 0;
disp[disp_index] = 0;
scre[scre_index] = 0;
LLOGLN(0, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]",
LLOGLN(10, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]",
host, disp, scre));
rv = atoi(disp);
return rv;
@ -219,7 +270,7 @@ connect_to_chansrv(void)
bytes = sizeof(saddr.sun_path);
snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis);
saddr.sun_path[bytes - 1] = 0;
LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
psaddr = (struct sockaddr *) &saddr;
bytes = sizeof(struct sockaddr_un);
error = connect(g_sck, psaddr, bytes);
@ -256,6 +307,8 @@ send_message(int code, char *data, int bytes)
pthread_mutex_unlock(&g_mutex);
return 1;
}
LLOGLN(10, ("send_message:"));
LHEXDUMP(10, (data, bytes));
pthread_mutex_unlock(&g_mutex);
return 0;
}
@ -392,7 +445,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
}
context = GET_UINT32(msg, 0);
status = GET_UINT32(msg, 4);
LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context));
LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", (int)context));
*phContext = context;
return status;
}
@ -463,7 +516,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
LLOGLN(10, ("SCardConnect:"));
LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
"dwPreferredProtocols %d",
hContext, szReader, dwShareMode, dwPreferredProtocols));
(int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols));
if (g_sck == -1)
{
LLOGLN(0, ("SCardConnect: error, not connected"));
@ -507,7 +560,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
status = GET_UINT32(msg, 8);
LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
"dwActiveProtocol %d",
status, *phCard, *pdwActiveProtocol));
status, (int)*phCard, (int)*pdwActiveProtocol));
return status;
}
@ -536,7 +589,7 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
int status;
LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
hCard, dwDisposition));
(int)hCard, (int)dwDisposition));
if (g_sck == -1)
{
LLOGLN(0, ("SCardDisconnect: error, not connected"));
@ -575,7 +628,7 @@ SCardBeginTransaction(SCARDHANDLE hCard)
int bytes;
int status;
LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", hCard));
LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", (int)hCard));
if (hCard == 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
@ -665,7 +718,7 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(10, ("SCardStatus:"));
if (hCard == 0)
{
LLOGLN(0, ("SCardStatus: error, bad hCard"));
LLOGLN(10, ("SCardStatus: error, bad hCard"));
return SCARD_F_INTERNAL_ERROR;
}
if (g_sck == -1)
@ -673,9 +726,9 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(0, ("SCardStatus: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" cchReaderLen %d", *pcchReaderLen));
LLOGLN(10, (" cbAtrLen %d", *pcbAtrLen));
LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
LLOGLN(10, (" cchReaderLen %d", (int)*pcchReaderLen));
LLOGLN(10, (" cbAtrLen %d", (int)*pcbAtrLen));
cchReaderLen = *pcchReaderLen;
msg = (char *) malloc(8192);
@ -703,10 +756,10 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen));
LLOGLN(10, ("SCardStatus: cchReaderLen in %d", (int)*pcchReaderLen));
offset = 0;
*pcchReaderLen = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardStatus: cchReaderLen out %d", *pcchReaderLen));
LLOGLN(10, ("SCardStatus: cchReaderLen out %d", (int)*pcchReaderLen));
offset += 4;
if (cchReaderLen > 0)
{
@ -721,14 +774,18 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName));
offset += *pcchReaderLen;
*pdwState = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardStatus: dwState %d", *pdwState));
if (*pdwState == 1)
{
*pdwState = 0x34;
}
LLOGLN(10, ("SCardStatus: dwState %d", (int)*pdwState));
offset += 4;
*pdwProtocol = GET_UINT32(msg, offset);
LLOGLN(10, ("SCardStatus: dwProtocol %d", *pdwProtocol));
LLOGLN(10, ("SCardStatus: dwProtocol %d", (int)*pdwProtocol));
offset += 4;
*pcbAtrLen = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, ("SCardStatus: cbAtrLen %d", *pcbAtrLen));
LLOGLN(10, ("SCardStatus: cbAtrLen %d", (int)*pcbAtrLen));
memcpy(pbAtr, msg + offset, *pcbAtrLen);
offset += *pcbAtrLen;
status = GET_UINT32(msg, offset);
@ -757,7 +814,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
char atr[36];
LLOGLN(10, ("SCardGetStatusChange:"));
LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders));
LLOGLN(10, (" dwTimeout %d cReaders %d", (int)dwTimeout, (int)cReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardGetStatusChange: error, not connected"));
@ -829,7 +886,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
}
cReaders = GET_UINT32(msg, 0);
offset = 4;
LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders));
LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", (int)cReaders));
for (index = 0; index < cReaders; index++)
{
rname = rgReaderStates[index].szReader;
@ -897,10 +954,10 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
LLOGLN(0, ("SCardControl: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, (" cbSendLength %d", cbSendLength));
LLOGLN(10, (" cbRecvLength %d", cbRecvLength));
LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
LLOGLN(10, (" dwControlCode 0x%8.8x", (int)dwControlCode));
LLOGLN(10, (" cbSendLength %d", (int)cbSendLength));
LLOGLN(10, (" cbRecvLength %d", (int)cbRecvLength));
/* #define SCARD_CTL_CODE(code) (0x42000000 + (code))
control_code = (control_code & 0x3ffc) >> 2;
@ -910,7 +967,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
dwControlCode = dwControlCode - 0x42000000;
dwControlCode = dwControlCode << 2;
dwControlCode = dwControlCode | (49 << 16);
LLOGLN(10, (" MS dwControlCode 0x%8.8x", dwControlCode));
LLOGLN(10, (" MS dwControlCode 0x%8.8d", (int)dwControlCode));
msg = (char *) malloc(8192);
offset = 0;
@ -946,7 +1003,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
}
offset = 0;
*lpBytesReturned = GET_UINT32(msg, offset);
LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned));
LLOGLN(10, (" cbRecvLength %d", (int)*lpBytesReturned));
offset += 4;
memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
offset += *lpBytesReturned;
@ -976,9 +1033,10 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
LLOGLN(0, ("SCardTransmit: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
LLOGLN(10, (" hCard 0x%8.8x", hCard));
LLOGLN(10, (" cbSendLength %d", cbSendLength));
LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
LLOGLN(10, (" cbSendLength %d", (int)cbSendLength));
LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength));
LLOGLN(10, (" pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol)));
LLOGLN(10, (" pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength)));
LLOGLN(10, (" pioRecvPci %p", pioRecvPci));
@ -993,9 +1051,11 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
offset += 4;
SET_UINT32(msg, offset, pioSendPci->dwProtocol);
offset += 4;
SET_UINT32(msg, offset, pioSendPci->cbPciLength);
/* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */
SET_UINT32(msg, offset, 8);
offset += 4;
extra_len = pioSendPci->cbPciLength - 8;
/* extra_len = pioSendPci->cbPciLength - 8; */
extra_len = 0;
SET_UINT32(msg, offset, extra_len);
offset += 4;
memcpy(msg + offset, pioSendPci + 1, extra_len);
@ -1070,8 +1130,9 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
*pcbRecvLength = GET_UINT32(msg, offset);
offset += 4;
LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength));
memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
LHEXDUMP(10, (pbRecvBuffer, *pcbRecvLength));
offset += *pcbRecvLength;
status = GET_UINT32(msg, offset);
free(msg);
@ -1113,12 +1174,16 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
LLOGLN(10, ("SCardListReaders:"));
LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups));
LLOGLN(10, ("SCardListReaders: *pcchReaders %d", *pcchReaders));
LLOGLN(10, ("SCardListReaders: *pcchReaders %d", (int)*pcchReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardListReaders: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
if ((mszGroups == NULL) && (mszReaders == NULL))
{
*pcchReaders = 0;
}
msg = (char *) malloc(8192);
offset = 0;
SET_UINT32(msg, offset, hContext);

@ -58,6 +58,15 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/rtpoll.h>
/* defined in pulse/version.h */
#if PA_PROTOCOL_VERSION > 28
/* these used to be defined in pulsecore/macro.h */
typedef bool pa_bool_t;
#define FALSE ((pa_bool_t) 0)
#define TRUE (!FALSE)
#else
#endif
#include "module-xrdp-sink-symdef.h"
PA_MODULE_AUTHOR("Jay Sorg");
@ -268,6 +277,19 @@ static int get_display_num_from_display(char *display_text) {
return display_num;
}
static int lsend(int fd, char *data, int bytes) {
int sent = 0;
int error;
while (sent < bytes) {
error = send(fd, data + sent, bytes - sent, 0);
if (error < 1) {
return error;
}
sent += error;
}
return sent;
}
static int data_send(struct userdata *u, pa_memchunk *chunk) {
char *data;
int bytes;
@ -316,7 +338,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) {
h.code = 0;
h.bytes = bytes + 8;
if (send(u->fd, &h, 8, 0) != 8) {
if (lsend(u->fd, (char*)(&h), 8) != 8) {
pa_log("data_send: send failed");
close(u->fd);
u->fd = 0;
@ -327,7 +349,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) {
data = (char*)pa_memblock_acquire(chunk->memblock);
data += chunk->index;
sent = send(u->fd, data, bytes, 0);
sent = lsend(u->fd, data, bytes);
pa_memblock_release(chunk->memblock);
if (sent != bytes) {
@ -349,7 +371,7 @@ static int close_send(struct userdata *u) {
}
h.code = 1;
h.bytes = 8;
if (send(u->fd, &h, 8, 0) != 8) {
if (lsend(u->fd, (char*)(&h), 8) != 8) {
pa_log("close_send: send failed");
close(u->fd);
u->fd = 0;

@ -45,6 +45,15 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/thread.h>
/* defined in pulse/version.h */
#if PA_PROTOCOL_VERSION > 28
/* these used to be defined in pulsecore/macro.h */
typedef bool pa_bool_t;
#define FALSE ((pa_bool_t) 0)
#define TRUE (!FALSE)
#else
#endif
#include "module-xrdp-source-symdef.h"
PA_MODULE_AUTHOR("Laxmikant Rashinkar");
@ -329,8 +338,7 @@ int pa__init(pa_module *m) {
pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
pa_source_new_data_set_sample_spec(&data, &ss);
pa_source_new_data_set_channel_map(&data, &map);
//pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Input"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp Input"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp source"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract");
u->source = pa_source_new(m->core, &data, PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY);
@ -361,7 +369,15 @@ int pa__init(pa_module *m) {
u->source->thread_info.max_rewind =
pa_usec_to_bytes(u->block_usec, &u->source->sample_spec);
if (!(u->thread = pa_thread_new("null-source", thread_func, u))) {
#if defined(PA_CHECK_VERSION)
#if PA_CHECK_VERSION(0, 9, 22)
if (!(u->thread = pa_thread_new("xrdp-source", thread_func, u))) {
#else
if (!(u->thread = pa_thread_new(thread_func, u))) {
#endif
#else
if (!(u->thread = pa_thread_new(thread_func, u)))
#endif
pa_log("Failed to create thread.");
goto fail;
}

@ -71,6 +71,8 @@ static int g_xrr_event_base = 0; /* non zero means we got extension */
static Cursor g_default_cursor = 0;
static char *g_override_window_title = 0;
/* used in valid field of struct rail_window_data */
#define RWD_X (1 << 0)
#define RWD_Y (1 << 1)
@ -620,6 +622,18 @@ rail_process_activate(struct stream *s, int size)
return 0;
}
/*****************************************************************************/
static int
rail_select_input(Window window_id)
{
XSelectInput(g_display, window_id,
PropertyChangeMask | StructureNotifyMask |
SubstructureNotifyMask | FocusChangeMask |
EnterWindowMask | LeaveWindowMask);
XSync(g_display, 0);
return 0;
}
/*****************************************************************************/
static int APP_CC
rail_restore_windows(void)
@ -637,6 +651,7 @@ rail_restore_windows(void)
XGetWindowAttributes(g_display, children[i], &window_attributes);
if (!window_attributes.override_redirect)
{
rail_select_input(children[i]);
if (window_attributes.map_state == IsViewable)
{
rail_win_set_state(children[i], 0x0); /* WithdrawnState */
@ -724,7 +739,7 @@ rail_win_get_state(Window win)
(unsigned char **)&data,
&nitems);
if (data || nitems > 0)
if (data && nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
@ -760,31 +775,40 @@ rail_win_set_state(Window win, unsigned long state)
}
/*****************************************************************************/
/* *data pointer that needs g_free */
static int APP_CC
rail_win_get_text(Window win, char **data)
{
int ret = 0;
int i = 0;
unsigned long nitems = 0;
unsigned char *ldata = 0;
char *lldata = 0;
if (g_override_window_title != 0)
{
*data = g_strdup(g_override_window_title);
return g_strlen(*data);
}
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
(unsigned char **)data, &nitems);
&ldata, &nitems);
if (ret != 0)
{
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
XFetchName(g_display, win, data);
XFetchName(g_display, win, &lldata);
*data = g_strdup(lldata);
i = g_strlen(*data);
XFree(lldata);
return i;
}
if (data)
*data = 0;
if (ldata)
{
char *ptr = *data;
for (; ptr != NULL; i++)
{
if (ptr[i] == '\0')
{
break;
}
}
*data = g_strdup((char *)ldata);
i = g_strlen(*data);
XFree(ldata);
return i;
}
return i;
@ -1207,6 +1231,7 @@ rail_win_send_text(Window win)
int crc;
struct rail_window_data* rwd;
LOG(10, ("chansrv::rail_win_send_text:"));
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@ -1219,7 +1244,7 @@ rail_win_send_text(Window win)
if (rwd->title_crc == crc)
{
LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed"));
XFree(data);
g_free(data);
XFree(rwd);
return 0;
}
@ -1229,13 +1254,15 @@ rail_win_send_text(Window win)
else
{
LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
g_free(data);
return 1;
}
if (data && len > 0) {
if (data && len > 0)
{
LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
win, data, len));
make_stream(s);
init_stream(s, 1024);
init_stream(s, len + 1024);
flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE;
out_uint32_le(s, 8); /* update title info */
out_uint32_le(s, win); /* window id */
@ -1251,10 +1278,7 @@ rail_win_send_text(Window win)
rwd->title_crc = crc;
rail_set_window_data(win, rwd);
}
if (data != 0)
{
XFree(data);
}
g_free(data);
XFree(rwd);
return 0;
}
@ -1355,7 +1379,8 @@ rail_create_window(Window window_id, Window owner_id)
flags = WINDOW_ORDER_TYPE_WINDOW;
}
title_size = rail_win_get_text(window_id, &title_bytes);
title_size = 0;
title_bytes = 0;
XGetTransientForHint(g_display, window_id, &transient_for);
@ -1363,21 +1388,24 @@ rail_create_window(Window window_id, Window owner_id)
{
style = RAIL_STYLE_TOOLTIP;
ext_style = RAIL_EXT_STYLE_TOOLTIP;
/* for tooltips, we don't grab the window text */
}
else if (transient_for > 0)
{
style = RAIL_STYLE_DIALOG;
ext_style = RAIL_EXT_STYLE_DIALOG;
owner_id = transient_for;
title_size = rail_win_get_text(window_id, &title_bytes);
}
else
{
style = RAIL_STYLE_NORMAL;
ext_style = RAIL_EXT_STYLE_NORMAL;
title_size = rail_win_get_text(window_id, &title_bytes);
}
make_stream(s);
init_stream(s, 1024);
init_stream(s, title_size + 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
@ -1387,6 +1415,7 @@ rail_create_window(Window window_id, Window owner_id)
out_uint32_le(s, ext_style); /* extended_style */
flags |= WINDOW_ORDER_FIELD_STYLE;
out_uint32_le(s, 0x05); /* show_state */
LOG(10, (" title %s", title_bytes));
flags |= WINDOW_ORDER_FIELD_SHOW;
if (title_size > 0)
{
@ -1449,7 +1478,7 @@ rail_create_window(Window window_id, Window owner_id)
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
XFree(title_bytes);
g_free(title_bytes);
rail_set_window_data(window_id, rwd);
XFree(rwd);
return 0;
@ -1608,7 +1637,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
init_stream(s, 1024);
init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@ -1692,7 +1721,7 @@ rail_configure_window(XConfigureEvent *config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
init_stream(s, 1024);
init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@ -1822,10 +1851,7 @@ rail_xevent(void *xevent)
case CreateNotify:
LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x",
lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
XSelectInput(g_display, lxevent->xcreatewindow.window,
PropertyChangeMask | StructureNotifyMask |
SubstructureNotifyMask | FocusChangeMask |
EnterWindowMask | LeaveWindowMask);
rail_select_input(lxevent->xcreatewindow.window);
break;
case DestroyNotify:
@ -1865,7 +1891,7 @@ rail_xevent(void *xevent)
XGetWindowAttributes(g_display, lxevent->xmap.window, &wnd_attributes);
if (wnd_attributes.map_state == IsViewable)
{
rail_create_window(lxevent->xmap.window, lxevent->xmap.event);
rail_create_window(lxevent->xmap.window, g_root_window);
if (!wnd_attributes.override_redirect)
{
rail_win_set_state(lxevent->xmap.window, 0x1); /* NormalState */
@ -1887,7 +1913,16 @@ rail_xevent(void *xevent)
LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window));
if (index >= 0)
{
XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
if (wnd_attributes.override_redirect)
{
// remove popups
rail_destroy_window(lxevent->xunmap.window);
list_remove_item(g_window_list, index);
} else {
rail_show_window(lxevent->xunmap.window, 0x0);
}
rv = 0;
}
}

@ -861,11 +861,6 @@ scard_make_new_ioctl(IRP *irp, tui32 ioctl)
struct stream *s;
xstream_new(s, 1024 * 4);
if (s == NULL)
{
log_error("system out of memory");
return s;
}
devredir_insert_DeviceIoRequest(s,
irp->DeviceId,

@ -603,6 +603,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_list_readers: "
"get_pcsc_context_by_app_context failed"));
g_free(groups);
return 1;
}
pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
@ -1489,6 +1490,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_get_status_change: "
"get_pcsc_context_by_app_context failed"));
g_free(rsa);
return 1;
}
scard_send_get_status_change(user_data,

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2009-2013
* Copyright (C) Jay Sorg 2009-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,14 +23,11 @@
#include <signal.h>
#include <sys/un.h>
#ifdef XRDP_LOAD_PULSE_MODULES
#include <pulse/util.h>
#endif
#include "sound.h"
#include "thread_calls.h"
#include "defines.h"
#include "fifo.h"
#include "file_loc.h"
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
@ -56,14 +53,6 @@ int g_buf_index = 0;
int g_sent_time[256];
int g_sent_flag[256];
#if defined(XRDP_SIMPLESOUND)
static void *DEFAULT_CC
read_raw_audio_data(void *arg);
#endif
#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d"
#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
struct xr_wave_format_ex
{
int wFormatTag;
@ -155,6 +144,25 @@ static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] =
static int g_client_input_format_index = 0;
static int g_server_input_format_index = 0;
/* microphone related */
static int APP_CC
sound_send_server_input_formats(void);
static int APP_CC
sound_process_input_format(int aindex, int wFormatTag,
int nChannels, int nSamplesPerSec,
int nAvgBytesPerSec, int nBlockAlign,
int wBitsPerSample, int cbSize, char *data);
static int APP_CC
sound_process_input_formats(struct stream *s, int size);
static int APP_CC
sound_input_start_recording(void);
static int APP_CC
sound_input_stop_recording(void);
static int APP_CC
sound_process_input_data(struct stream *s, int bytes);
static int DEFAULT_CC
sound_sndsrvr_source_data_in(struct trans *trans);
/*****************************************************************************/
static int APP_CC
sound_send_server_output_formats(void)
@ -224,7 +232,6 @@ sound_send_server_output_formats(void)
}
/*****************************************************************************/
static int
sound_send_training(void)
{
@ -365,13 +372,15 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
if ((data_bytes < 4) || (data_bytes > 128 * 1024))
{
LOG(0, ("sound_send_wave_data_chunk: bad data_bytes %d", data_bytes));
return 0;
return 1;
}
LOG(20, ("sound_send_wave_data_chunk: g_sent_flag[%d] = %d",
g_cBlockNo + 1, g_sent_flag[(g_cBlockNo + 1) & 0xff]));
if (g_sent_flag[(g_cBlockNo + 1) & 0xff] & 1)
{
LOG(10, ("sound_send_wave_data_chunk: no room"));
return 0;
return 2;
}
else
{
@ -430,9 +439,12 @@ sound_send_wave_data(char *data, int data_bytes)
int space_left;
int chunk_bytes;
int data_index;
int error;
int res;
LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
data_index = 0;
error = 0;
while (data_bytes > 0)
{
space_left = BBUF_SIZE - g_buf_index;
@ -440,19 +452,33 @@ sound_send_wave_data(char *data, int data_bytes)
if (chunk_bytes < 1)
{
LOG(10, ("sound_send_wave_data: error"));
error = 1;
break;
}
g_memcpy(g_buffer + g_buf_index, data + data_index, chunk_bytes);
g_buf_index += chunk_bytes;
if (g_buf_index >= BBUF_SIZE)
{
sound_send_wave_data_chunk(g_buffer, BBUF_SIZE);
g_buf_index = 0;
res = sound_send_wave_data_chunk(g_buffer, BBUF_SIZE);
if (res == 2)
{
/* don't need to error on this */
LOG(0, ("sound_send_wave_data: dropped, no room"));
break;
}
else if (res != 0)
{
LOG(10, ("sound_send_wave_data: error"));
error = 1;
break;
}
}
data_bytes -= chunk_bytes;
data_index += chunk_bytes;
}
return 0;
return error;
}
/*****************************************************************************/
@ -467,9 +493,18 @@ sound_send_close(void)
LOG(10, ("sound_send_close:"));
/* send any left over data */
sound_send_wave_data_chunk(g_buffer, g_buf_index);
if (g_buf_index)
{
if (sound_send_wave_data_chunk(g_buffer, g_buf_index) != 0)
{
LOG(10, ("sound_send_close: sound_send_wave_data_chunk failed"));
return 1;
}
}
g_buf_index = 0;
g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
/* send close msg */
make_stream(s);
init_stream(s, 8182);
out_uint16_le(s, SNDC_CLOSE);
@ -522,23 +557,23 @@ sound_process_wave_confirm(struct stream *s, int size)
/*****************************************************************************/
/* process message in from the audio source, eg pulse, alsa
on it's way to the client */
on it's way to the client. returns error */
static int APP_CC
process_pcm_message(int id, int size, struct stream *s)
{
switch (id)
{
case 0:
sound_send_wave_data(s->p, size);
return sound_send_wave_data(s->p, size);
break;
case 1:
sound_send_close();
return sound_send_close();
break;
default:
LOG(10, ("process_pcm_message: unknown id %d", id));
break;
}
return 0;
return 1;
}
/*****************************************************************************/
@ -652,11 +687,6 @@ sound_init(void)
g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
#ifdef XRDP_LOAD_PULSE_MODULES
if (load_pulse_modules())
LOG(0, ("Audio and microphone redirection will not work!"));
#endif
/* init sound output */
sound_send_server_output_formats();
@ -682,13 +712,6 @@ sound_init(void)
/* save data from sound_server_source */
fifo_init(&in_fifo, 100);
#if defined(XRDP_SIMPLESOUND)
/* start thread to read raw audio data from pulseaudio device */
tc_thread_create(read_raw_audio_data, 0);
#endif
return 0;
}
@ -696,6 +719,7 @@ sound_init(void)
int APP_CC
sound_deinit(void)
{
LOG(10, ("sound_deinit:"));
if (g_audio_l_trans_out != 0)
{
trans_delete(g_audio_l_trans_out);
@ -722,10 +746,6 @@ sound_deinit(void)
fifo_deinit(&in_fifo);
#ifdef XRDP_LOAD_PULSE_MODULES
system("pulseaudio --kill");
#endif
return 0;
}
@ -814,180 +834,49 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
sound_check_wait_objs(void)
{
if (g_audio_l_trans_out != 0)
{
trans_check_wait_objs(g_audio_l_trans_out);
if (trans_check_wait_objs(g_audio_l_trans_out) != 0)
{
LOG(10, ("sound_check_wait_objs: g_audio_l_trans_out returned non-zero"));
trans_delete(g_audio_l_trans_out);
g_audio_l_trans_out = 0;
}
}
if (g_audio_c_trans_out != 0)
{
trans_check_wait_objs(g_audio_c_trans_out);
}
if (g_audio_l_trans_in != 0)
{
trans_check_wait_objs(g_audio_l_trans_in);
}
if (g_audio_c_trans_in != 0)
{
trans_check_wait_objs(g_audio_c_trans_in);
}
return 0;
}
/**
* Load xrdp pulseaudio sink and source modules
*
* @return 0 on success, -1 on failure
*****************************************************************************/
#ifdef XRDP_LOAD_PULSE_MODULES
static int APP_CC
load_pulse_modules()
{
struct sockaddr_un sa;
pid_t pid;
char* cli;
int fd;
int i;
int rv;
char buf[1024];
/* is pulse audio daemon running? */
if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
{
LOG(0, ("load_pulse_modules: No PulseAudio daemon running, "
"or not running as session daemon"));
}
/* get name of unix domain socket used by pulseaudio for CLI */
if ((cli = (char *) pa_runtime_path("cli")) == NULL)
{
LOG(0, ("load_pulse_modules: Error getting PulesAudio runtime path"));
return -1;
}
/* open a socket */
if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
{
pa_xfree(cli);
LOG(0, ("load_pulse_modules: Socket open error"));
return -1;
}
/* set it up */
memset(&sa, 0, sizeof(struct sockaddr_un));
sa.sun_family = AF_UNIX;
pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path));
pa_xfree(cli);
for (i = 0; i < 20; i++)
{
if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0)
LOG(0, ("load_pulse_modules: Failed to kill PulseAudio daemon"));
if ((rv = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 &&
(errno != ECONNREFUSED && errno != ENOENT))
if (trans_check_wait_objs(g_audio_c_trans_out) != 0)
{
LOG(0, ("load_pulse_modules: connect() failed with error: %s",
strerror(errno)));
return -1;
LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero"));
trans_delete(g_audio_c_trans_out);
g_audio_c_trans_out = 0;
}
if (rv >= 0)
break;
pa_msleep(300);
}
if (i >= 20)
{
LOG(0, ("load_pulse_modules: Daemon not responding"));
return -1;
}
LOG(0, ("load_pulse_modules: connected to pulseaudio daemon"));
/* read back PulseAudio sign on message */
memset(buf, 0, 1024);
recv(fd, buf, 1024, 0);
/* send cmd to load source module */
memset(buf, 0, 1024);
sprintf(buf, "load-module module-xrdp-source\n");
send(fd, buf, strlen(buf), 0);
/* read back response */
memset(buf, 0, 1024);
recv(fd, buf, 1024, 0);
if (strcasestr(buf, "Module load failed") != 0)
{
LOG(0, ("load_pulse_modules: Error loading module-xrdp-source"));
}
else
if (g_audio_l_trans_in != 0)
{
LOG(0, ("load_pulse_modules: Loaded module-xrdp-source"));
/* success, set it as the default source */
memset(buf, 0, 1024);
sprintf(buf, "set-default-source xrdp-source\n");
send(fd, buf, strlen(buf), 0);
memset(buf, 0, 1024);
recv(fd, buf, 1024, 0);
if (strcasestr(buf, "does not exist") != 0)
{
LOG(0, ("load_pulse_modules: Error setting default source"));
}
else
if (trans_check_wait_objs(g_audio_l_trans_in) != 0)
{
LOG(0, ("load_pulse_modules: set default source"));
LOG(10, ("sound_check_wait_objs: g_audio_l_trans_in returned non-zero"));
trans_delete(g_audio_l_trans_in);
g_audio_l_trans_in = 0;
}
}
/* send cmd to load sink module */
memset(buf, 0, 1024);
sprintf(buf, "load-module module-xrdp-sink\n");
send(fd, buf, strlen(buf), 0);
/* read back response */
memset(buf, 0, 1024);
recv(fd, buf, 1024, 0);
if (strcasestr(buf, "Module load failed") != 0)
{
LOG(0, ("load_pulse_modules: Error loading module-xrdp-sink"));
}
else
if (g_audio_c_trans_in != 0)
{
LOG(0, ("load_pulse_modules: Loaded module-xrdp-sink"));
/* success, set it as the default sink */
memset(buf, 0, 1024);
sprintf(buf, "set-default-sink xrdp-sink\n");
send(fd, buf, strlen(buf), 0);
memset(buf, 0, 1024);
recv(fd, buf, 1024, 0);
if (strcasestr(buf, "does not exist") != 0)
{
LOG(0, ("load_pulse_modules: Error setting default sink"));
}
else
if (trans_check_wait_objs(g_audio_c_trans_in) != 0)
{
LOG(0, ("load_pulse_modules: set default sink"));
LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero"));
trans_delete(g_audio_c_trans_in);
g_audio_c_trans_in = 0;
}
}
close(fd);
return 0;
}
#endif
/******************************************************************************
** **
@ -1152,7 +1041,7 @@ sound_process_input_formats(struct stream *s, int size)
*****************************************************************************/
static int APP_CC
sound_input_start_recording()
sound_input_start_recording(void)
{
struct stream* s;
@ -1186,7 +1075,7 @@ sound_input_start_recording()
*****************************************************************************/
static int APP_CC
sound_input_stop_recording()
sound_input_stop_recording(void)
{
struct stream* s;
@ -1252,14 +1141,14 @@ sound_sndsrvr_source_data_in(struct trans *trans)
return 1;
ts = trans_get_in_s(trans);
trans_force_read(trans, 3);
if (trans_force_read(trans, 3))
log_message(LOG_LEVEL_ERROR, "sound.c: error reading from transport");
ts->p = ts->data + 8;
in_uint8(ts, cmd);
in_uint16_le(ts, bytes_req);
if (bytes_req != 0)
xstream_new(s, bytes_req + 2);
xstream_new(s, bytes_req + 2);
if (cmd == PA_CMD_SEND_DATA)
{
@ -1309,7 +1198,6 @@ sound_sndsrvr_source_data_in(struct trans *trans)
s_mark_end(s);
trans_force_write_s(trans, s);
xstream_free(s);
}
else if (cmd == PA_CMD_START_REC)
{
@ -1320,133 +1208,7 @@ sound_sndsrvr_source_data_in(struct trans *trans)
sound_input_stop_recording();
}
return 0;
}
/*****************************************************************************/
#if defined(XRDP_SIMPLESOUND)
#define AUDIO_BUF_SIZE 2048
xstream_free(s);
static int DEFAULT_CC
sttrans_data_in(struct trans *self)
{
LOG(0, ("sttrans_data_in:\n"));
return 0;
}
/**
* read raw audio data from pulseaudio device and write it
* to a unix domain socket on which trans server is listening
*/
static void *DEFAULT_CC
read_raw_audio_data(void *arg)
{
pa_sample_spec samp_spec;
pa_simple *simple = NULL;
uint32_t bytes_read;
char *cptr;
int i;
int error;
struct trans *strans;
char path[256];
struct stream *outs;
strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
if (strans == 0)
{
LOG(0, ("read_raw_audio_data: trans_create failed\n"));
return 0;
}
strans->trans_data_in = sttrans_data_in;
g_snprintf(path, 255, CHANSRV_PORT_OUT_STR, g_display_num);
if (trans_connect(strans, "", path, 100) != 0)
{
LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
trans_delete(strans);
return 0;
}
/* setup audio format */
samp_spec.format = PA_SAMPLE_S16LE;
samp_spec.rate = 44100;
samp_spec.channels = 2;
/* if we are root, then for first 8 seconds connection to pulseaudo server
fails; if we are non-root, then connection succeeds on first attempt;
for now we have changed code to be non-root, but this may change in the
future - so pretend we are root and try connecting to pulseaudio server
for upto one minute */
for (i = 0; i < 60; i++)
{
simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
"record", &samp_spec, NULL, NULL, &error);
if (simple)
{
/* connected to pulseaudio server */
LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
break;
}
LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
g_sleep(1000);
}
if (i == 60)
{
/* failed to connect to audio server */
trans_delete(strans);
return NULL;
}
/* insert header just once */
outs = trans_get_out_s(strans, 8192);
out_uint32_le(outs, 0);
out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
cptr = outs->p;
out_uint8s(outs, AUDIO_BUF_SIZE);
s_mark_end(outs);
while (1)
{
/* read a block of raw audio data... */
g_memset(cptr, 0, 4);
bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);
if (bytes_read < 0)
{
LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
break;
}
/* bug workaround:
even when there is no audio data, pulseaudio is returning without
errors but the data itself is zero; we use this zero data to
determine that there is no audio data present */
if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
{
g_sleep(10);
continue;
}
if (trans_force_write_s(strans, outs) != 0)
{
LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
break;
}
}
pa_simple_free(simple);
trans_delete(strans);
return NULL;
}
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2009-2013
* Copyright (C) Jay Sorg 2009-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,11 +19,6 @@
#ifndef _SOUND_H_
#define _SOUND_H_
#if defined(XRDP_SIMPLESOUND)
#include <pulse/simple.h>
#include <pulse/error.h>
#endif
#include "arch.h"
#include "parse.h"
#include "os_calls.h"
@ -63,17 +58,4 @@ int APP_CC sound_check_wait_objs(void);
int APP_CC sound_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length);
/* microphone related */
static int APP_CC sound_send_server_input_formats(void);
static int APP_CC sound_process_input_format(int aindex, int wFormatTag,
int nChannels, int nSamplesPerSec, int nAvgBytesPerSec,
int nBlockAlign, int wBitsPerSample, int cbSize, char *data);
static int APP_CC sound_process_input_formats(struct stream *s, int size);
static int APP_CC sound_input_start_recording();
static int APP_CC sound_input_stop_recording();
static int APP_CC sound_process_input_data(struct stream *s, int bytes);
static int DEFAULT_CC sound_sndsrvr_source_data_in(struct trans *trans);
static int APP_CC load_pulse_modules();
#endif

@ -74,9 +74,10 @@ config_read(struct config_sesman *cfg)
/* read global config */
config_read_globals(fd, cfg, param_n, param_v);
/* read Xvnc/X11rdp parameter list */
/* read Xvnc/X11rdp/XOrg parameter list */
config_read_vnc_params(fd, cfg, param_n, param_v);
config_read_rdp_params(fd, cfg, param_n, param_v);
config_read_xorg_params(fd, cfg, param_n, param_v);
/* read logging config */
// config_read_logging(fd, &(cfg->log), param_n, param_v);
@ -87,6 +88,8 @@ config_read(struct config_sesman *cfg)
/* read session config */
config_read_sessions(fd, &(cfg->sess), param_n, param_v);
config_read_session_variables(fd, cfg, param_n, param_v);
/* cleanup */
list_delete(sec);
list_delete(param_v);
@ -336,6 +339,7 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
se->max_idle_time = 0;
se->max_disc_time = 0;
se->kill_disconnected = 0;
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v);
@ -367,15 +371,49 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
{
se->max_disc_time = g_atoi((char *)list_get_item(param_v, i));
}
if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_POLICY_S))
{
char *value = (char *)list_get_item(param_v, i);
if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_DFLT_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
}
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBD_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_UBD;
}
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBI_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_UBI;
}
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBC_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_UBC;
}
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDI_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_UBDI;
}
else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDC_S))
{
se->policy = SESMAN_CFG_SESS_POLICY_UBDC;
}
else /* silently ignore typos */
{
se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
}
}
}
/* printing security config */
/* printing session config */
g_printf("session configuration:\r\n");
g_printf("\tMaxSessions: %i\r\n", se->max_sessions);
g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset);
g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected);
g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time);
g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time);
g_printf("\tPolicy: %i\r\n", se->policy);
return 0;
}
@ -410,6 +448,38 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
return 0;
}
/******************************************************************************/
int DEFAULT_CC
config_read_xorg_params(int file, struct config_sesman *cs,
struct list *param_n, struct list *param_v)
{
int i;
list_clear(param_v);
list_clear(param_n);
cs->xorg_params = list_create();
file_read_section(file, SESMAN_CFG_XORG_PARAMS, param_n, param_v);
for (i = 0; i < param_n->count; i++)
{
list_add_item(cs->xorg_params,
(long) g_strdup((char *) list_get_item(param_v, i)));
}
/* printing security config */
g_printf("XOrg parameters:\r\n");
for (i = 0; i < cs->xorg_params->count; i++)
{
g_printf("\tParameter %02d %s\r\n",
i, (char *) list_get_item(cs->xorg_params, i));
}
return 0;
}
/******************************************************************************/
int DEFAULT_CC
config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
@ -439,3 +509,39 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
return 0;
}
/******************************************************************************/
int DEFAULT_CC
config_read_session_variables(int file, struct config_sesman *cs,
struct list *param_n, struct list *param_v)
{
int i;
list_clear(param_v);
list_clear(param_n);
cs->session_variables1 = list_create();
cs->session_variables2 = list_create();
file_read_section(file, SESMAN_CFG_SESSION_VARIABLES, param_n, param_v);
for (i = 0; i < param_n->count; i++)
{
list_add_item(cs->session_variables1,
(tintptr) g_strdup((char *) list_get_item(param_n, i)));
list_add_item(cs->session_variables2,
(tintptr) g_strdup((char *) list_get_item(param_v, i)));
}
/* printing security config */
g_writeln("%s parameters:", SESMAN_CFG_SESSION_VARIABLES);
for (i = 0; i < cs->session_variables1->count; i++)
{
g_writeln(" Parameter %02d %s=%s", i,
(char *) list_get_item(cs->session_variables1, i),
(char *) list_get_item(cs->session_variables2, i));
}
return 0;
}

@ -42,8 +42,11 @@
#define SESMAN_CFG_AUTH_FILE_PATH "AuthFilePath"
#define SESMAN_CFG_RDP_PARAMS "X11rdp"
#define SESMAN_CFG_XORG_PARAMS "Xorg"
#define SESMAN_CFG_VNC_PARAMS "Xvnc"
#define SESMAN_CFG_SESSION_VARIABLES "SessionVariables"
/*
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
@ -64,6 +67,29 @@
#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit"
#define SESMAN_CFG_SESS_DISC_LIMIT "DisconnectedTimeLimit"
#define SESMAN_CFG_SESS_POLICY_S "Policy"
#define SESMAN_CFG_SESS_POLICY_DFLT_S "Default"
#define SESMAN_CFG_SESS_POLICY_UBD_S "UBD"
#define SESMAN_CFG_SESS_POLICY_UBI_S "UBI"
#define SESMAN_CFG_SESS_POLICY_UBC_S "UBC"
#define SESMAN_CFG_SESS_POLICY_UBDI_S "UBDI"
#define SESMAN_CFG_SESS_POLICY_UBDC_S "UBDC"
enum SESMAN_CFG_SESS_POLICY_BITS {
SESMAN_CFG_SESS_POLICY_D = 0x01,
SESMAN_CFG_SESS_POLICY_I = 0x02,
SESMAN_CFG_SESS_POLICY_C = 0x04
};
enum SESMAN_CFG_SESS_POLICY {
SESMAN_CFG_SESS_POLICY_DFLT = 0,
SESMAN_CFG_SESS_POLICY_UBD = SESMAN_CFG_SESS_POLICY_D,
SESMAN_CFG_SESS_POLICY_UBI = SESMAN_CFG_SESS_POLICY_I,
SESMAN_CFG_SESS_POLICY_UBC = SESMAN_CFG_SESS_POLICY_C,
SESMAN_CFG_SESS_POLICY_UBDI = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_I,
SESMAN_CFG_SESS_POLICY_UBDC = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_C
};
/**
*
* @struct config_security
@ -134,6 +160,11 @@ struct config_sessions
* @brief enables automatic killing of disconnected session
*/
int kill_disconnected;
/**
* @var policy
* @brief session allocation policy
*/
enum SESMAN_CFG_SESS_POLICY policy;
};
/**
@ -192,6 +223,13 @@ struct config_sesman
* @var log
* @brief Log configuration struct
*/
struct list* xorg_params;
/**
* @var log
* @brief Log configuration struct
*/
//struct log_config log;
/**
* @var sec
@ -203,6 +241,9 @@ struct config_sesman
* @brief Session configuration options struct
*/
struct config_sessions sess;
struct list* session_variables1;
struct list* session_variables2;
};
/**
@ -285,6 +326,19 @@ int DEFAULT_CC
config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n,
struct list* param_v);
/**
*
* @brief Reads sesman [XOrg] configuration section
* @param file configuration file descriptor
* @param cs pointer to a config_sesman struct
* @param param_n parameter name list
* @param param_v parameter value list
* @return 0 on success, 1 on failure
*
*/
int DEFAULT_CC
config_read_xorg_params(int file, struct config_sesman* cs, struct list* param_n,
struct list* param_v);
/**
*
@ -300,4 +354,8 @@ int DEFAULT_CC
config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n,
struct list* param_v);
int DEFAULT_CC
config_read_session_variables(int file, struct config_sesman *cs,
struct list *param_n, struct list *param_v);
#endif

@ -24,6 +24,8 @@
*
*/
#include "list.h"
#include "sesman.h"
#include "sys/types.h"
@ -60,12 +62,16 @@ env_check_password_file(char *filename, char *password)
/******************************************************************************/
int DEFAULT_CC
env_set_user(char *username, char *passwd_file, int display)
env_set_user(char *username, char *passwd_file, int display,
struct list *env_names, struct list* env_values)
{
int error;
int pw_uid;
int pw_gid;
int uid;
int index;
char *name;
char *value;
char pw_shell[256];
char pw_dir[256];
char pw_gecos[256];
@ -96,7 +102,7 @@ env_set_user(char *username, char *passwd_file, int display)
{
g_clearenv();
g_setenv("SHELL", pw_shell, 1);
g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1);
g_setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
g_setenv("USER", username, 1);
g_sprintf(text, "%d", uid);
g_setenv("UID", text, 1);
@ -106,6 +112,16 @@ env_set_user(char *username, char *passwd_file, int display)
g_setenv("DISPLAY", text, 1);
g_setenv("LANG", "en_US.UTF-8", 1);
g_setenv("XRDP_SESSION", "1", 1);
if ((env_names != 0) && (env_values != 0) &&
(env_names->count == env_values->count))
{
for (index = 0; index < env_names->count; index++)
{
name = (char *) list_get_item(env_names, index),
value = (char *) list_get_item(env_values, index),
g_setenv(name, value, 1);
}
}
if (passwd_file != 0)
{
@ -113,7 +129,11 @@ env_set_user(char *username, char *passwd_file, int display)
{
/* if no auth_file_path is set, then we go for
$HOME/.vnc/sesman_username_passwd */
g_mkdir(".vnc");
if (g_mkdir(".vnc") < 0)
{
log_message(LOG_LEVEL_ERROR,
"env_set_user: error creating .vnc dir");
}
g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
else

@ -27,6 +27,8 @@
#ifndef ENV_H
#define ENV_H
#include "list.h"
/**
*
* @brief Creates vnc password file
@ -48,6 +50,7 @@ env_check_password_file(char* filename, char* password);
*
*/
int DEFAULT_CC
env_set_user(char* username, char* passwd_file, int display);
env_set_user(char* username, char* passwd_file, int display,
struct list *env_names, struct list* env_values);
#endif

@ -58,12 +58,19 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
case SCP_SESSION_TYPE_XVNC:
s->type = SCP_SESSION_TYPE_XVNC;
break;
case SCP_SESSION_TYPE_XRDP:
s->type = SCP_SESSION_TYPE_XRDP;
break;
case SCP_SESSION_TYPE_XORG:
s->type = SCP_SESSION_TYPE_XORG;
break;
case SCP_GW_AUTHENTICATION:
s->type = SCP_GW_AUTHENTICATION;
break;
case SCP_SESSION_TYPE_MANAGE:
s->type = SCP_SESSION_TYPE_MANAGE;
s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1);
@ -75,6 +82,7 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
}
break;
default:
log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
return 1;

@ -41,6 +41,8 @@
#define SCP_SESSION_TYPE_XVNC 0x00
#define SCP_SESSION_TYPE_XRDP 0x01
#define SCP_SESSION_TYPE_MANAGE 0x02
#define SCP_SESSION_TYPE_XORG 0x03
/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway
* XRDP sends this command to let sesman verify if the user is allowed
* to use the gateway */

@ -56,6 +56,10 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
out_uint16_be(c->out_s, 10);
}
else if (s->type == SCP_SESSION_TYPE_XORG)
{
out_uint16_be(c->out_s, 20);
}
else
{
log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
@ -191,7 +195,7 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
in_uint16_be(c->in_s, code);
if (code == 0 || code == 10)
if (code == 0 || code == 10 || code == 20)
{
session = scp_session_create();
@ -207,10 +211,14 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
{
scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
}
else
else if (code == 10)
{
scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
}
else if (code == 20)
{
scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
}
/* reading username */
in_uint16_be(c->in_s, sz);

@ -74,7 +74,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
else if (data)
{
s_item = session_get_bydata(s->username, s->width, s->height,
s->bpp, s->type);
s->bpp, s->type, s->client_ip);
if (s_item != 0)
{
@ -122,13 +122,22 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
s->domain, s->program, s->directory,
s->client_ip);
}
else
else if (SCP_SESSION_TYPE_XRDP == s->type)
{
log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
s->domain, s->program, s->directory,
s->client_ip);
}
else if (SCP_SESSION_TYPE_XORG == s->type)
{
/* type is SCP_SESSION_TYPE_XORG */
log_message(LOG_LEVEL_INFO, "starting Xorg session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XORG,
s->domain, s->program, s->directory,
s->client_ip);
}
}
else

@ -195,8 +195,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
parseCommonStates(e, "scp_v1s_list_sessions()");
break;
}
g_free(slist);
}
/* resource management */
@ -208,6 +206,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* cleanup */
scp_session_destroy(s);
auth_end(data);
g_free(slist);
}
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)

@ -54,7 +54,14 @@ sesman_main_loop(void)
/*main program loop*/
log_message(LOG_LEVEL_INFO, "listening...");
g_sck = g_tcp_socket();
if (g_sck < 0)
{
log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
return 1;
}
g_tcp_set_non_blocking(g_sck);
error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
@ -132,7 +139,8 @@ sesman_main_loop(void)
g_get_errno(), g_get_strerror());
}
g_tcp_close(g_sck);
if (g_sck != -1)
g_tcp_close(g_sck);
}
/******************************************************************************/
@ -308,9 +316,17 @@ main(int argc, char **argv)
g_file_close(1);
g_file_close(2);
g_file_open("/dev/null");
g_file_open("/dev/null");
g_file_open("/dev/null");
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
}
/* initializing locks */
@ -361,7 +377,11 @@ main(int argc, char **argv)
/* make sure the /tmp/.X11-unix directory exist */
if (!g_directory_exist("/tmp/.X11-unix"))
{
g_create_dir("/tmp/.X11-unix");
if (!g_create_dir("/tmp/.X11-unix"))
{
log_message(LOG_LEVEL_ERROR,
"sesman.c: error creating dir /tmp/.X11-unix");
}
g_chmod_hex("/tmp/.X11-unix", 0x1777);
}

@ -15,17 +15,47 @@ TerminalServerAdmins=tsadmins
AlwaysGroupCheck = false
[Sessions]
## X11DisplayOffset - x11 display number offset
# Type: integer
# Default: 10
X11DisplayOffset=10
## MaxSessions - maximum number of connections to an xrdp server
# Type: integer
# Default: 0
MaxSessions=50
## KillDisconnected - kill disconnected sessions
# Type: integer
# Default: 0
# if 1, true, or yes, kill session after 60 seconds
KillDisconnected=0
## IdleTimeLimit - when to disconnect idle sessions
# Type: integer
# Default: 0
# if not zero, the seconds without mouse or keyboard input before disconnect
# not complete yet
IdleTimeLimit=0
## DisconnectedTimeLimit - when to kill idle sessions
# Type: integer
# Default: 0
# if not zero, the seconds before a disconnected session is killed
# min 60 seconds
DisconnectedTimeLimit=0
## Policy - session allocation policy
# Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
# Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
# "UBD" session per <User,BitPerPixel,DisplaySize>
# "UBI" session per <User,BitPerPixel,IPAddr>
# "UBC" session per <User,BitPerPixel,Connection>
# "UBDI" session per <User,BitPerPixel,DisplaySize,IPAddr>
# "UBDC" session per <User,BitPerPixel,DisplaySize,Connection>
Policy=Default
[Logging]
LogFile=xrdp-sesman.log
LogLevel=DEBUG
@ -47,3 +77,20 @@ param4=tcp
param5=-localhost
param6=-dpi
param7=96
[Xorg]
param1=-config
param2=xrdp/xorg.conf
param3=-logfile
param4=/dev/null
param5=-noreset
param6=-ac
param7=-nolisten
param8=tcp
[Chansrv]
# drive redirection, defaults to xrdp_client if not set
FuseMountName=thinclient_drives
[SessionVariables]
PULSE_SCRIPT=/etc/xrdp/pulse/default.pa

@ -90,9 +90,10 @@ dumpItemsToString(struct list *self, char *outstr, int len)
/******************************************************************************/
struct session_item *DEFAULT_CC
session_get_bydata(char *name, int width, int height, int bpp, int type)
session_get_bydata(char *name, int width, int height, int bpp, int type, char *client_ip)
{
struct session_chain *tmp;
enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy;
/*THREAD-FIX require chain lock */
lock_chain_acquire();
@ -104,23 +105,49 @@ session_get_bydata(char *name, int width, int height, int bpp, int type)
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
policy |= SESMAN_CFG_SESS_POLICY_D; /* Xvnc cannot resize */
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
break;
case SCP_SESSION_TYPE_XORG:
type = SESMAN_SESSION_TYPE_XORG;
break;
default:
lock_chain_release();
return 0;
}
#if 0
log_message(LOG_LEVEL_INFO,
"session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s",
policy, name, width, height, bpp, type, client_ip);
#endif
while (tmp != 0)
{
#if 0
log_message(LOG_LEVEL_INFO,
"session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s",
tmp->item,
tmp->item->name,
tmp->item->width, tmp->item->height,
tmp->item->bpp, tmp->item->type,
tmp->item->client_ip);
#endif
if (type == SESMAN_SESSION_TYPE_XRDP)
{
/* only name and bpp need to match for X11rdp, it can resize */
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
tmp->item->bpp == bpp &&
tmp->item->type == type)
(!(policy & SESMAN_CFG_SESS_POLICY_D) ||
(tmp->item->width == width && tmp->item->height == height)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_I) ||
(g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_C) ||
(g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
tmp->item->bpp == bpp &&
tmp->item->type == type)
{
/*THREAD-FIX release chain lock */
lock_chain_release();
@ -129,10 +156,13 @@ session_get_bydata(char *name, int width, int height, int bpp, int type)
}
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
tmp->item->width == width &&
tmp->item->height == height &&
tmp->item->bpp == bpp &&
tmp->item->type == type)
(tmp->item->width == width && tmp->item->height == height) &&
(!(policy & SESMAN_CFG_SESS_POLICY_I) ||
(g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
(!(policy & SESMAN_CFG_SESS_POLICY_C) ||
(g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
tmp->item->bpp == bpp &&
tmp->item->type == type)
{
/*THREAD-FIX release chain lock */
lock_chain_release();
@ -173,26 +203,62 @@ x_server_running_check_ports(int display)
if (!x_running) /* check 59xx */
{
sck = g_tcp_socket();
g_sprintf(text, "59%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
if ((sck = g_tcp_socket()) != -1)
{
g_sprintf(text, "59%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
}
}
if (!x_running) /* check 60xx */
{
sck = g_tcp_socket();
g_sprintf(text, "60%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
if ((sck = g_tcp_socket()) != -1)
{
g_sprintf(text, "60%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
}
}
if (!x_running) /* check 62xx */
{
sck = g_tcp_socket();
g_sprintf(text, "62%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
if ((sck = g_tcp_socket()) != -1)
{
g_sprintf(text, "62%2.2d", display);
x_running = g_tcp_bind(sck, text);
g_tcp_close(sck);
}
}
if (!x_running)
{
g_sprintf(text, XRDP_CHANSRV_STR, display);
x_running = g_file_exist(text);
}
if (!x_running)
{
g_sprintf(text, CHANSRV_PORT_OUT_STR, display);
x_running = g_file_exist(text);
}
if (!x_running)
{
g_sprintf(text, CHANSRV_PORT_IN_STR, display);
x_running = g_file_exist(text);
}
if (!x_running)
{
g_sprintf(text, CHANSRV_API_STR, display);
x_running = g_file_exist(text);
}
if (!x_running)
{
g_sprintf(text, XRDP_X11RDP_STR, display);
x_running = g_file_exist(text);
}
return x_running;
@ -258,7 +324,8 @@ session_start_sessvc(int xpid, int wmpid, long data, char *username, int display
list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
env_set_user(username, 0, display);
env_set_user(username, 0, display,
g_cfg->session_variables1, g_cfg->session_variables2);
/* executing sessvc */
g_execvp(exe_path, ((char **)sessvc_params->items));
@ -471,7 +538,9 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (pampid == 0) /* child: X11/client */
{
env_set_user(username, 0, display);
env_set_user(username, 0, display,
g_cfg->session_variables1,
g_cfg->session_variables2);
if (x_server_running(display))
{
auth_set_env(data);
@ -564,7 +633,9 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (xpid == 0) /* child */
{
env_set_user(username, passwd_file, display);
env_set_user(username, passwd_file, display,
g_cfg->session_variables1,
g_cfg->session_variables2);
env_check_password_file(passwd_file, password);
g_snprintf(text, 255, "%d", g_cfg->sess.max_idle_time);
@ -574,10 +645,40 @@ session_start_fork(int width, int height, int bpp, char *username,
g_snprintf(text, 255, "%d", g_cfg->sess.kill_disconnected);
g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
if (type == SESMAN_SESSION_TYPE_XVNC)
if (type == SESMAN_SESSION_TYPE_XORG)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
/* these are the must have parameters */
list_add_item(xserver_params, (long) g_strdup("/usr/bin/Xorg"));
list_add_item(xserver_params, (long) g_strdup(screen));
/* additional parameters from sesman.ini file */
list_append_list_strdup(g_cfg->xorg_params, xserver_params, 0);
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **) xserver_params->items;
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
/* some args are passed via env vars */
g_sprintf(geometry, "%d", width);
g_setenv("XRDP_START_WIDTH", geometry, 1);
g_sprintf(geometry, "%d", height);
g_setenv("XRDP_START_HEIGHT", geometry, 1);
/* fire up Xorg */
g_execvp("/usr/bin/Xorg", pp1);
}
else if (type == SESMAN_SESSION_TYPE_XVNC)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
/* these are the must have parameters */
list_add_item(xserver_params, (long)g_strdup("Xvnc"));
list_add_item(xserver_params, (long)g_strdup(screen));
@ -596,13 +697,14 @@ session_start_fork(int width, int height, int bpp, char *username,
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("Xvnc", pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
/* these are the must have parameters */
list_add_item(xserver_params, (long)g_strdup("X11rdp"));
list_add_item(xserver_params, (long)g_strdup(screen));
@ -619,7 +721,7 @@ session_start_fork(int width, int height, int bpp, char *username,
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("X11rdp", pp1);
}
else
@ -693,8 +795,12 @@ session_start_fork(int width, int height, int bpp, char *username,
/*THREAD-FIX release chain lock */
lock_chain_release();
return display;
}
g_free(temp->item);
g_free(temp);
return display;
}
@ -713,7 +819,8 @@ session_reconnect_fork(int display, char *username)
}
else if (pid == 0)
{
env_set_user(username, 0, display);
env_set_user(username, 0, display,
g_cfg->session_variables1, g_cfg->session_variables2);
g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
if (g_file_exist(text))
@ -936,6 +1043,7 @@ session_get_bypid(int pid)
"pid %d is null!", pid);
/*THREAD-FIX release chain lock */
lock_chain_release();
g_free(dummy);
return 0;
}
@ -954,6 +1062,7 @@ session_get_bypid(int pid)
/*THREAD-FIX release chain lock */
lock_chain_release();
g_free(dummy);
return 0;
}

@ -30,8 +30,9 @@
#include "libscp_types.h"
#define SESMAN_SESSION_TYPE_XRDP 1
#define SESMAN_SESSION_TYPE_XVNC 2
#define SESMAN_SESSION_TYPE_XRDP 1
#define SESMAN_SESSION_TYPE_XVNC 2
#define SESMAN_SESSION_TYPE_XORG 3
#define SESMAN_SESSION_STATUS_ACTIVE 0x01
#define SESMAN_SESSION_STATUS_IDLE 0x02
@ -90,9 +91,9 @@ struct session_chain
*
*/
struct session_item* DEFAULT_CC
session_get_bydata(char* name, int width, int height, int bpp, int type);
session_get_bydata(char* name, int width, int height, int bpp, int type, char *client_ip);
#ifndef session_find_item
#define session_find_item(a, b, c, d, e) session_get_bydata(a, b, c, d, e);
#define session_find_item(a, b, c, d, e, f) session_get_bydata(a, b, c, d, e, f);
#endif
/**

@ -86,6 +86,7 @@ sig_sesman_reload_cfg(int sig)
if (config_read(cfg) != 0)
{
log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
g_free(cfg);
return;
}

@ -58,7 +58,12 @@ int main(int argc, char **argv)
return 1;
}
sck = socket(PF_UNIX, SOCK_DGRAM, 0);
if ((sck = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0)
{
printf("socket open error\n");
return 1;
}
len = sizeof(sa);
if (sendto(sck, "sig", 4, 0, (struct sockaddr *)&sa, len) > 0)

@ -107,6 +107,12 @@ int main(int argc, char **argv)
scp_init(&logging);
sock = g_tcp_socket();
if (sock < 0)
{
LOG_DBG("Socket open error, g_tcp_socket() failed\n");
return 1;
}
s = scp_session_create();
c = scp_connection_create(sock);
@ -179,16 +185,16 @@ void cmndList(struct SCP_CONNECTION *c)
(dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \
(dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute);
}
if (0 != dsl)
{
g_free(dsl);
}
}
else
{
printf("No sessions.\n");
}
if (0 != dsl)
{
g_free(dsl);
}
}
void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s)

@ -75,7 +75,10 @@ main(int argc, char **argv)
init_stream(in_s, 8192);
make_stream(out_s);
init_stream(out_s, 8192);
sck = g_tcp_socket();
if (sck < 0)
return 1;
if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0)
{

@ -38,6 +38,9 @@ int main(int argc, char **argv)
scp_init(&log);
sock = g_tcp_socket();
if (sock < 0)
return 1;
s = scp_session_create();
c = scp_connection_create(sock);

@ -122,6 +122,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
*errorcode = error ;
}
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}
@ -135,6 +136,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
}
g_printf("pam_authenticate failed: %s\r\n",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}
@ -153,6 +155,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
}
g_printf("pam_acct_mgmt failed: %s\r\n",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}

@ -967,7 +967,16 @@ lib_mod_connect(struct vnc *v)
make_stream(s);
g_sprintf(con_port, "%s", v->port);
make_stream(pixel_format);
v->sck = g_tcp_socket();
if (v->sck < 0)
{
v->server_msg(v, "VNC error: socket create error, g_tcp_socket() failed", 0);
free_stream(s);
free_stream(pixel_format);
return 1;
}
v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0);
v->sck_closed = 0;
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);

@ -59,10 +59,8 @@ remove_modules()
while IFS=: read mod_file mod_dir mod_args
do
if [ -d build_dir/$mod_dir ]; then
rm -rf build_dir/$mod_dir
fi
done < ../$data_file
(cd build_dir; [ -d $mod_dir ] && rm -rf $mod_dir)
done < $data_file
}
extract_it()

@ -508,7 +508,7 @@ KbdAddEvent(int down, int param1, int param2, int param3, int param4);
void
KbdSync(int param1);
int
rdpLoadLayout(int keylayout);
rdpLoadLayout(struct xrdp_client_info *client_info);
/* rdpup.c */
int

@ -282,7 +282,7 @@ rdpChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
/******************************************************************************/
int
rdpLoadLayout(int keylayout)
rdpLoadLayout(struct xrdp_client_info *client_info)
{
XkbRMLVOSet set;
XkbSrvInfoPtr xkbi;
@ -292,8 +292,10 @@ rdpLoadLayout(int keylayout)
KeyCode first_key;
CARD8 num_keys;
LLOGLN(0, ("rdpLoadLayout: keylayout 0x%8.8x display %s",
keylayout, display));
int keylayout = client_info->keylayout;
LLOGLN(0, ("rdpLoadLayout: keylayout 0x%8.8x variant %s display %s",
keylayout, client_info->variant, display));
memset(&set, 0, sizeof(set));
if (g_use_evdev)
{
@ -303,42 +305,26 @@ rdpLoadLayout(int keylayout)
{
set.rules = "base";
}
set.model = "pc104";
set.layout = "us";
switch (keylayout)
{
case 0x00000407: /* German */
set.layout = "de";
break;
case 0x00000409: /* US */
set.layout = "us";
break;
case 0x0000040C: /* French */
set.layout = "fr";
break;
case 0x00000410: /* Italian */
set.layout = "it";
break;
case 0x00000416: /* Portuguese (Brazilian ABNT) */
set.model = "abnt2";
set.layout = "br";
break;
case 0x00000419: /* Russian */
set.layout = "ru";
break;
case 0x0000041D: /* Swedish */
set.layout = "se";
break;
case 0x00000816: /* Portuguese */
set.layout = "pt";
break;
default:
LLOGLN(0, ("rdpLoadLayout: unknown keylayout 0x%8.8x", keylayout));
break;
}
set.variant = "";
set.options = "";
if (strlen(client_info->model) > 0)
{
set.model = client_info->model;
}
if (strlen(client_info->variant) > 0)
{
set.variant = client_info->variant;
}
if (strlen(client_info->layout) > 0)
{
set.layout = client_info->layout;
}
retry:
/* free some stuff so we can call InitKeyboardDeviceStruct again */
xkbi = g_keyboard->key->xkbInfo;
xkb = xkbi->desc;
@ -355,21 +341,30 @@ rdpLoadLayout(int keylayout)
rdpChangeKeyboardControl))
{
LLOGLN(0, ("rdpLoadLayout: InitKeyboardDeviceStruct failed"));
return 1;
}
/* notify the X11 clients eg. X_ChangeKeyboardMapping */
keySyms = XkbGetCoreMap(g_keyboard);
first_key = keySyms->minKeyCode;
num_keys = (keySyms->maxKeyCode - keySyms->minKeyCode) + 1;
XkbApplyMappingChange(g_keyboard, keySyms, first_key, num_keys,
NULL, serverClient);
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
if (keySyms)
{
if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
first_key = keySyms->minKeyCode;
num_keys = (keySyms->maxKeyCode - keySyms->minKeyCode) + 1;
XkbApplyMappingChange(g_keyboard, keySyms, first_key, num_keys,
NULL, serverClient);
for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
{
XkbApplyMappingChange(pDev, keySyms, first_key, num_keys,
NULL, serverClient);
if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
{
XkbApplyMappingChange(pDev, keySyms, first_key, num_keys,
NULL, serverClient);
}
}
} else
{
/* sometimes, variant doesn't support all layouts */
set.variant = "";
goto retry;
}
return 0;

@ -1117,7 +1117,7 @@ rdpup_process_msg(struct stream *s)
g_do_multimon = 0;
}
rdpLoadLayout(g_rdpScreen.client_info.keylayout);
rdpLoadLayout(&(g_rdpScreen.client_info));
}
else if (msg_type == 105)
@ -1563,7 +1563,7 @@ convert_pixel(int in_pixel)
if (g_rdpScreen.depth == 24)
{
if (g_rdpScreen.rdp_bpp == 24)
if (g_rdpScreen.rdp_bpp >= 24)
{
rv = in_pixel;
SPLITCOLOR32(red, green, blue, rv);
@ -1619,7 +1619,7 @@ convert_pixels(void *src, void *dst, int num_pixels)
{
src32 = (unsigned int *)src;
if (g_rdpScreen.rdp_bpp == 24)
if (g_rdpScreen.rdp_bpp >= 24)
{
dst32 = (unsigned int *)dst;

@ -59,7 +59,7 @@ mkfontdir-1.0.6.tar.bz2 : mkfontdir-1.0.6
mkfontscale-1.0.8.tar.bz2 : mkfontscale-1.0.8 :
xkbcomp-1.2.0.tar.bz2 : xkbcomp-1.2.0 :
xdriinfo-1.0.4.tar.bz2 : xdriinfo-1.0.4 :
xorg-server-1.9.3.tar.bz2 : xorg-server-1.9.3 : --with-sha1=libcrypto --disable-dmx
xorg-server-1.9.3.tar.bz2 : xorg-server-1.9.3 : --with-sha1=libcrypto --disable-dmx --without-dtrace
applewmproto-1.4.1.tar.bz2 : applewmproto-1.4.1 :
bdftopcf-1.0.3.tar.bz2 : bdftopcf-1.0.3 :
intltool-0.41.1.tar.gz : intltool-0.41.1 :

@ -1,3 +1,4 @@
moduledir := $(shell pkg-config xorg-server --variable moduledir)
all: allmake
@ -16,7 +17,20 @@ allclean:
cd xrdpmouse; $(MAKE) clean
xinstall:
strip module/libxorgxrdp.so
strip xrdpdev/xrdpdev_drv.so
strip xrdpmouse/xrdpmouse_drv.so
strip xrdpkeyb/xrdpkeyb_drv.so
mkdir -p $(HOME)/xorg-modules/drivers $(HOME)/xorg-modules/input
cp module/libxorgxrdp.so $(HOME)/xorg-modules/
cp xrdpdev/xrdpdev_drv.so $(HOME)/xorg-modules/drivers/
cp xrdpmouse/xrdpmouse_drv.so $(HOME)/xorg-modules/input/
cp xrdpkeyb/xrdpkeyb_drv.so $(HOME)/xorg-modules/input/
install:
install --directory $(DESTDIR)$(moduledir) $(DESTDIR)$(moduledir)/drivers $(DESTDIR)$(moduledir)/input
install --mode=0644 --strip module/libxorgxrdp.so $(DESTDIR)$(moduledir)
install --mode=0644 --strip xrdpdev/xrdpdev_drv.so $(DESTDIR)$(moduledir)/drivers/
install --mode=0644 --strip xrdpmouse/xrdpmouse_drv.so $(DESTDIR)$(moduledir)/input/
install --mode=0644 --strip xrdpkeyb/xrdpkeyb_drv.so $(DESTDIR)$(moduledir)/input/

@ -6,11 +6,16 @@ rdpPolyFillArc.o rdpPolyText8.o rdpPolyText16.o rdpImageText8.o \
rdpImageText16.o rdpImageGlyphBlt.o rdpPolyGlyphBlt.o rdpPushPixels.o \
rdpCursor.o rdpMain.o rdpRandR.o rdpMisc.o rdpReg.o \
rdpComposite.o rdpGlyphs.o rdpPixmap.o rdpInput.o rdpClientCon.o rdpCapture.o \
rdpTrapezoids.o
rdpTrapezoids.o rdpXv.o rdpSimd.o
;OBJS += cpuid_x86.o i420_to_rgb32_x86_sse2.o yv12_to_rgb32_x86_sse2.o yuy2_to_rgb32_x86_sse2.o uyvy_to_rgb32_x86_sse2.o
;OBJS += cpuid_amd64.o i420_to_rgb32_amd64_sse2.o yv12_to_rgb32_amd64_sse2.o yuy2_to_rgb32_amd64_sse2.o uyvy_to_rgb32_amd64_sse2.o
CFLAGS = -g -O2 -Wall -fPIC -I/usr/include/xorg -I/usr/include/pixman-1 \
-I../../../common
;CFLAGS += -DSIMD_USE_ACCEL=1
LDFLAGS =
LIBS =
@ -22,3 +27,34 @@ libxorgxrdp.so: $(OBJS) Makefile
clean:
rm -f $(OBJS) libxorgxrdp.so
cpuid_x86.o: x86/cpuid_x86.asm
yasm -f elf32 -g dwarf2 x86/cpuid_x86.asm
i420_to_rgb32_x86_sse2.o: x86/i420_to_rgb32_x86_sse2.asm
yasm -f elf32 -g dwarf2 x86/i420_to_rgb32_x86_sse2.asm
yv12_to_rgb32_x86_sse2.o: x86/yv12_to_rgb32_x86_sse2.asm
yasm -f elf32 -g dwarf2 x86/yv12_to_rgb32_x86_sse2.asm
yuy2_to_rgb32_x86_sse2.o: x86/yuy2_to_rgb32_x86_sse2.asm
yasm -f elf32 -g dwarf2 x86/yuy2_to_rgb32_x86_sse2.asm
uyvy_to_rgb32_x86_sse2.o: x86/uyvy_to_rgb32_x86_sse2.asm
yasm -f elf32 -g dwarf2 x86/uyvy_to_rgb32_x86_sse2.asm
cpuid_amd64.o: amd64/cpuid_amd64.asm
yasm -f elf64 -g dwarf2 amd64/cpuid_amd64.asm
i420_to_rgb32_amd64_sse2.o: amd64/i420_to_rgb32_amd64_sse2.asm
yasm -f elf64 -g dwarf2 amd64/i420_to_rgb32_amd64_sse2.asm
yv12_to_rgb32_amd64_sse2.o: amd64/yv12_to_rgb32_amd64_sse2.asm
yasm -f elf64 -g dwarf2 amd64/yv12_to_rgb32_amd64_sse2.asm
yuy2_to_rgb32_amd64_sse2.o: amd64/yuy2_to_rgb32_amd64_sse2.asm
yasm -f elf64 -g dwarf2 amd64/yuy2_to_rgb32_amd64_sse2.asm
uyvy_to_rgb32_amd64_sse2.o: amd64/uyvy_to_rgb32_amd64_sse2.asm
yasm -f elf64 -g dwarf2 amd64/uyvy_to_rgb32_amd64_sse2.asm

@ -0,0 +1,41 @@
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
;The first six integer or pointer arguments are passed in registers
;RDI, RSI, RDX, RCX, R8, and R9
;int
;cpuid_amd64(int eax_in, int ecx_in, int *eax, int *ebx, int *ecx, int *edx)
PROC cpuid_amd64
; save registers
push rbx
push rdx
push rcx
push r8
push r9
mov rax, rdi
mov rcx, rsi
cpuid
pop rdi
mov [rdi], edx
pop rdi
mov [rdi], ecx
pop rdi
mov [rdi], ebx
pop rdi
mov [rdi], eax
mov eax, 0
; restore registers
pop rbx
ret;
align 16

@ -0,0 +1,39 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
amd64 asm functions
*/
#ifndef __FUNCS_AMD64_H
#define __FUNCS_AMD64_H
int
cpuid_amd64(int eax_in, int ecx_in, int *eax, int *ebx, int *ecx, int *edx);
int
yv12_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
i420_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
yuy2_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
uyvy_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
#endif

@ -0,0 +1,248 @@
;
;Copyright 2014 Jay Sorg
;
;Permission to use, copy, modify, distribute, and sell this software and its
;documentation for any purpose is hereby granted without fee, provided that
;the above copyright notice appear in all copies and that both that
;copyright notice and this permission notice appear in supporting
;documentation.
;
;The above copyright notice and this permission notice shall be included in
;all copies or substantial portions of the Software.
;
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
;AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;I420 to RGB32
;amd64 SSE2 32 bit
;
; RGB to YUV
; 0.299 0.587 0.114
; -0.14713 -0.28886 0.436
; 0.615 -0.51499 -0.10001
; YUV to RGB
; 1 0 1.13983
; 1 -0.39465 -0.58060
; 1 2.03211 0
; shift left 12
; 4096 0 4669
; 4096 -1616 -2378
; 4096 9324 0
SECTION .data
align 16
c128 times 8 dw 128
c4669 times 8 dw 4669
c1616 times 8 dw 1616
c2378 times 8 dw 2378
c9324 times 8 dw 9324
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
do8_uv:
; v
movd xmm1, [rbx] ; 4 at a time
lea rbx, [rbx + 4]
punpcklbw xmm1, xmm1
pxor xmm6, xmm6
punpcklbw xmm1, xmm6
movdqa xmm7, [rel c128]
psubw xmm1, xmm7
psllw xmm1, 4
; v
movd xmm2, [rdx] ; 4 at a time
lea rdx, [rdx + 4]
punpcklbw xmm2, xmm2
punpcklbw xmm2, xmm6
psubw xmm2, xmm7
psllw xmm2, 4
do8:
; y
movq xmm0, [rsi] ; 8 at a time
lea rsi, [rsi + 8]
pxor xmm6, xmm6
punpcklbw xmm0, xmm6
; r = y + hiword(4669 * (v << 4))
movdqa xmm4, [rel c4669]
pmulhw xmm4, xmm1
movdqa xmm3, xmm0
paddw xmm3, xmm4
; g = y - hiword(1616 * (u << 4)) - hiword(2378 * (v << 4))
movdqa xmm5, [rel c1616]
pmulhw xmm5, xmm2
movdqa xmm6, [rel c2378]
pmulhw xmm6, xmm1
movdqa xmm4, xmm0
psubw xmm4, xmm5
psubw xmm4, xmm6
; b = y + hiword(9324 * (u << 4))
movdqa xmm6, [rel c9324]
pmulhw xmm6, xmm2
movdqa xmm5, xmm0
paddw xmm5, xmm6
packuswb xmm3, xmm3 ; b
packuswb xmm4, xmm4 ; g
punpcklbw xmm3, xmm4 ; gb
pxor xmm4, xmm4 ; a
packuswb xmm5, xmm5 ; r
punpcklbw xmm5, xmm4 ; ar
movdqa xmm4, xmm3
punpcklwd xmm3, xmm5 ; argb
movdqa [rdi], xmm3
lea rdi, [rdi + 16]
punpckhwd xmm4, xmm5 ; argb
movdqa [rdi], xmm4
lea rdi, [rdi + 16]
ret;
;The first six integer or pointer arguments are passed in registers
; RDI, RSI, RDX, RCX, R8, and R9
;int
;i420_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC i420_to_rgb32_amd64_sse2
push rbx
push rsi
push rdi
push rbp
push rdi
push rdx
mov rdi, rcx ; rgbs
mov rcx, rsi ; width
mov rdx, rcx
pop rbp ; height
mov rax, rbp
shr rbp, 1
imul rax, rcx ; rax = width * height
pop rsi ; y
mov rbx, rsi ; u = y + width * height
add rbx, rax
; local vars
; char* yptr1
; char* yptr2
; char* uptr
; char* vptr
; int* rgbs1
; int* rgbs2
; int width
sub rsp, 56 ; local vars, 56 bytes
mov [rsp + 0], rsi ; save y1
add rsi, rdx
mov [rsp + 8], rsi ; save y2
mov [rsp + 16], rbx ; save u
shr rax, 2
add rbx, rax ; v = u + (width * height / 4)
mov [rsp + 24], rbx ; save v
mov [rsp + 32], rdi ; save rgbs1
mov rax, rdx
shl rax, 2
add rdi, rax
mov [rsp + 40], rdi ; save rgbs2
loop_y:
mov rcx, rdx ; width
shr rcx, 3
; save rdx
mov [rsp + 48], rdx
;prefetchnta 4096[rsp + 0] ; y
;prefetchnta 1024[rsp + 16] ; u
;prefetchnta 1024[rsp + 24] ; v
loop_x:
mov rsi, [rsp + 0] ; y1
mov rbx, [rsp + 16] ; u
mov rdx, [rsp + 24] ; v
mov rdi, [rsp + 32] ; rgbs1
; y1
call do8_uv
mov [rsp + 0], rsi ; y1
mov [rsp + 32], rdi ; rgbs1
mov rsi, [rsp + 8] ; y2
mov rdi, [rsp + 40] ; rgbs2
; y2
call do8
mov [rsp + 8], rsi ; y2
mov [rsp + 16], rbx ; u
mov [rsp + 24], rdx ; v
mov [rsp + 40], rdi ; rgbs2
dec rcx ; width
jnz loop_x
; restore rdx
mov rdx, [rsp + 48]
; update y1 and 2
mov rax, [rsp + 0]
mov rbx, rdx
add rax, rbx
mov [rsp + 0], rax
mov rax, [rsp + 8]
add rax, rbx
mov [rsp + 8], rax
; update rgb1 and 2
mov rax, [rsp + 32]
mov rbx, rdx
shl rbx, 2
add rax, rbx
mov [rsp + 32], rax
mov rax, [rsp + 40]
add rax, rbx
mov [rsp + 40], rax
mov rcx, rbp
dec rcx ; height
mov rbp, rcx
jnz loop_y
add rsp, 56
mov rax, 0
pop rbp
pop rdi
pop rsi
pop rbx
ret
align 16

@ -0,0 +1,17 @@
%macro PROC 1
align 16
global %1
%1:
%endmacro
;int
;uyvy_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC uyvy_to_rgb32_amd64_sse2
push rbx
mov rax, 0
pop rbx
ret
align 16

@ -0,0 +1,17 @@
%macro PROC 1
align 16
global %1
%1:
%endmacro
;int
;yuy2_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC yuy2_to_rgb32_amd64_sse2
push rbx
mov rax, 0
pop rbx
ret
align 16

@ -0,0 +1,248 @@
;
;Copyright 2014 Jay Sorg
;
;Permission to use, copy, modify, distribute, and sell this software and its
;documentation for any purpose is hereby granted without fee, provided that
;the above copyright notice appear in all copies and that both that
;copyright notice and this permission notice appear in supporting
;documentation.
;
;The above copyright notice and this permission notice shall be included in
;all copies or substantial portions of the Software.
;
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
;AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;YV12 to RGB32
;amd64 SSE2 32 bit
;
; RGB to YUV
; 0.299 0.587 0.114
; -0.14713 -0.28886 0.436
; 0.615 -0.51499 -0.10001
; YUV to RGB
; 1 0 1.13983
; 1 -0.39465 -0.58060
; 1 2.03211 0
; shift left 12
; 4096 0 4669
; 4096 -1616 -2378
; 4096 9324 0
SECTION .data
align 16
c128 times 8 dw 128
c4669 times 8 dw 4669
c1616 times 8 dw 1616
c2378 times 8 dw 2378
c9324 times 8 dw 9324
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
do8_uv:
; u
movd xmm1, [rbx] ; 4 at a time
lea rbx, [rbx + 4]
punpcklbw xmm1, xmm1
pxor xmm6, xmm6
punpcklbw xmm1, xmm6
movdqa xmm7, [rel c128]
psubw xmm1, xmm7
psllw xmm1, 4
; v
movd xmm2, [rdx] ; 4 at a time
lea rdx, [rdx + 4]
punpcklbw xmm2, xmm2
punpcklbw xmm2, xmm6
psubw xmm2, xmm7
psllw xmm2, 4
do8:
; y
movq xmm0, [rsi] ; 8 at a time
lea rsi, [rsi + 8]
pxor xmm6, xmm6
punpcklbw xmm0, xmm6
; r = y + hiword(4669 * (v << 4))
movdqa xmm4, [rel c4669]
pmulhw xmm4, xmm2
movdqa xmm3, xmm0
paddw xmm3, xmm4
; g = y - hiword(1616 * (u << 4)) - hiword(2378 * (v << 4))
movdqa xmm5, [rel c1616]
pmulhw xmm5, xmm1
movdqa xmm6, [rel c2378]
pmulhw xmm6, xmm2
movdqa xmm4, xmm0
psubw xmm4, xmm5
psubw xmm4, xmm6
; b = y + hiword(9324 * (u << 4))
movdqa xmm6, [rel c9324]
pmulhw xmm6, xmm1
movdqa xmm5, xmm0
paddw xmm5, xmm6
packuswb xmm3, xmm3 ; b
packuswb xmm4, xmm4 ; g
punpcklbw xmm3, xmm4 ; gb
pxor xmm4, xmm4 ; a
packuswb xmm5, xmm5 ; r
punpcklbw xmm5, xmm4 ; ar
movdqa xmm4, xmm3
punpcklwd xmm3, xmm5 ; argb
movdqa [rdi], xmm3
lea rdi, [rdi + 16]
punpckhwd xmm4, xmm5 ; argb
movdqa [rdi], xmm4
lea rdi, [rdi + 16]
ret;
;The first six integer or pointer arguments are passed in registers
; RDI, RSI, RDX, RCX, R8, and R9
;int
;yv12_to_rgb32_amd64_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC yv12_to_rgb32_amd64_sse2
push rbx
push rsi
push rdi
push rbp
push rdi
push rdx
mov rdi, rcx ; rgbs
mov rcx, rsi ; width
mov rdx, rcx
pop rbp ; height
mov rax, rbp
shr rbp, 1
imul rax, rcx ; rax = width * height
pop rsi ; y
mov rbx, rsi ; u = y + width * height
add rbx, rax
; local vars
; char* yptr1
; char* yptr2
; char* uptr
; char* vptr
; int* rgbs1
; int* rgbs2
; int width
sub rsp, 56 ; local vars, 56 bytes
mov [rsp + 0], rsi ; save y1
add rsi, rdx
mov [rsp + 8], rsi ; save y2
mov [rsp + 16], rbx ; save u
shr rax, 2
add rbx, rax ; v = u + (width * height / 4)
mov [rsp + 24], rbx ; save v
mov [rsp + 32], rdi ; save rgbs1
mov rax, rdx
shl rax, 2
add rdi, rax
mov [rsp + 40], rdi ; save rgbs2
loop_y:
mov rcx, rdx ; width
shr rcx, 3
; save rdx
mov [rsp + 48], rdx
;prefetchnta 4096[rsp + 0] ; y
;prefetchnta 1024[rsp + 16] ; u
;prefetchnta 1024[rsp + 24] ; v
loop_x:
mov rsi, [rsp + 0] ; y1
mov rbx, [rsp + 16] ; u
mov rdx, [rsp + 24] ; v
mov rdi, [rsp + 32] ; rgbs1
; y1
call do8_uv
mov [rsp + 0], rsi ; y1
mov [rsp + 32], rdi ; rgbs1
mov rsi, [rsp + 8] ; y2
mov rdi, [rsp + 40] ; rgbs2
; y2
call do8
mov [rsp + 8], rsi ; y2
mov [rsp + 16], rbx ; u
mov [rsp + 24], rdx ; v
mov [rsp + 40], rdi ; rgbs2
dec rcx ; width
jnz loop_x
; restore rdx
mov rdx, [rsp + 48]
; update y1 and 2
mov rax, [rsp + 0]
mov rbx, rdx
add rax, rbx
mov [rsp + 0], rax
mov rax, [rsp + 8]
add rax, rbx
mov [rsp + 8], rax
; update rgb1 and 2
mov rax, [rsp + 32]
mov rbx, rdx
shl rbx, 2
add rax, rbx
mov [rsp + 32], rax
mov rax, [rsp + 40]
add rax, rbx
mov [rsp + 40], rax
mov rcx, rbp
dec rcx ; height
mov rbp, rcx
jnz loop_y
add rsp, 56
mov rax, 0
pop rbp
pop rdi
pop rsi
pop rbx
ret
align 16

@ -30,9 +30,46 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdpPri.h"
#define XRDP_MODULE_NAME "XRDPMOD"
#define XRDP_DRIVER_NAME "XRDPDEV"
#define XRDP_MOUSE_NAME "XRDPMOUSE"
#define XRDP_KEYB_NAME "XRDPKEYB"
#define XRDP_VERSION 1000
#define PACKAGE_VERSION_MAJOR 1
#define PACKAGE_VERSION_MINOR 0
#define PACKAGE_VERSION_PATCHLEVEL 0
#define COLOR8(r, g, b) \
((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6))
#define COLOR15(r, g, b) \
((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0))
#define COLOR16(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0))
#define COLOR24(r, g, b) \
((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16))
#define SPLITCOLOR32(r, g, b, c) \
do { \
r = ((c) >> 16) & 0xff; \
g = ((c) >> 8) & 0xff; \
b = (c) & 0xff; \
} while (0)
/* PIXMAN_a8b8g8r8 */
#define XRDP_a8b8g8r8 \
((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
/* PIXMAN_a8r8g8b8 */
#define XRDP_a8r8g8b8 \
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
/* PIXMAN_r5g6b5 */
#define XRDP_r5g6b5 \
((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5)
/* PIXMAN_a1r5g5b5 */
#define XRDP_a1r5g5b5 \
((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5)
/* PIXMAN_r3g3b2 */
#define XRDP_r3g3b2 \
((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2)
#define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))
@ -40,7 +77,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RDPMIN(_val1, _val2) ((_val1) < (_val2) ? (_val1) : (_val2))
#define RDPMAX(_val1, _val2) ((_val1) < (_val2) ? (_val2) : (_val1))
#define RDPCLAMP(_val, _lo, _hi) \
(_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val)
(_val) < (_lo) ? (_lo) : (_val) > (_hi) ? (_hi) : (_val)
#define RDPALIGN(_val, _al) ((((long)(_val)) + ((_al) - 1)) & ~((_al) - 1))
#define XRDP_CD_NODRAW 0
#define XRDP_CD_NOCLIP 1
@ -157,6 +195,8 @@ struct _rdpCounts
CARD32 callCount[64 - 23];
};
typedef int (*yuv_to_rgb32_proc)(unsigned char *yuvs, int width, int height, int *rgbs);
/* move this to common header */
struct _rdpRec
{
@ -228,6 +268,15 @@ struct _rdpRec
struct _rdpCounts counts;
yuv_to_rgb32_proc i420_to_rgb32;
yuv_to_rgb32_proc yv12_to_rgb32;
yuv_to_rgb32_proc yuy2_to_rgb32;
yuv_to_rgb32_proc uyvy_to_rgb32;
char *xv_data;
int xv_data_bytes;
int xv_timer_schedualed;
OsTimerPtr xv_timer;
};
typedef struct _rdpRec rdpRec;
typedef struct _rdpRec * rdpPtr;
@ -250,63 +299,63 @@ typedef struct _rdpGCRec * rdpGCPtr;
struct urdp_draw_item_fill
{
int opcode;
int fg_color;
int bg_color;
int pad0;
int opcode;
int fg_color;
int bg_color;
int pad0;
};
struct urdp_draw_item_img
{
int opcode;
int pad0;
int opcode;
int pad0;
};
struct urdp_draw_item_line
{
int opcode;
int fg_color;
int bg_color;
int width;
xSegment* segs;
int nseg;
int flags;
int opcode;
int fg_color;
int bg_color;
int width;
xSegment* segs;
int nseg;
int flags;
};
struct urdp_draw_item_scrblt
{
int srcx;
int srcy;
int dstx;
int dsty;
int cx;
int cy;
int srcx;
int srcy;
int dstx;
int dsty;
int cx;
int cy;
};
struct urdp_draw_item_text
{
int opcode;
int fg_color;
struct rdp_text* rtext; /* in rdpglyph.h */
int opcode;
int fg_color;
struct rdp_text* rtext; /* in rdpglyph.h */
};
union urdp_draw_item
{
struct urdp_draw_item_fill fill;
struct urdp_draw_item_img img;
struct urdp_draw_item_line line;
struct urdp_draw_item_scrblt scrblt;
struct urdp_draw_item_text text;
struct urdp_draw_item_fill fill;
struct urdp_draw_item_img img;
struct urdp_draw_item_line line;
struct urdp_draw_item_scrblt scrblt;
struct urdp_draw_item_text text;
};
struct rdp_draw_item
{
int type; /* RDI_FILL, RDI_IMGLL, ... */
int flags;
struct rdp_draw_item* prev;
struct rdp_draw_item* next;
RegionPtr reg;
union urdp_draw_item u;
int type; /* RDI_FILL, RDI_IMGLL, ... */
int flags;
struct rdp_draw_item* prev;
struct rdp_draw_item* next;
RegionPtr reg;
union urdp_draw_item u;
};
#define XRDP_USE_COUNT_THRESHOLD 1

@ -33,34 +33,249 @@
#include "rdpDraw.h"
#include "rdpClientCon.h"
#include "rdpReg.h"
#include "rdpMisc.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define RDP_MAX_TILES 1024
/******************************************************************************/
static int
rdpLimitRects(RegionPtr reg, int max_rects, BoxPtr *rects)
{
int nrects;
nrects = REGION_NUM_RECTS(reg);
if (nrects > max_rects)
{
nrects = 1;
*rects = rdpRegionExtents(reg);
}
else
{
*rects = REGION_RECTS(reg);
}
return nrects;
}
/******************************************************************************/
/* copy rects with no error checking */
static int
rdpCopyBox_a8r8g8b8_to_a8r8g8b8(void *src, int src_stride, int srcx, int srcy,
void *dst, int dst_stride, int dstx, int dsty,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
int index;
int jndex;
int bytes;
int height;
BoxPtr box;
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + (box->y1 - srcy) * src_stride;
s8 += (box->x1 - srcx) * 4;
d8 = ((char *) dst) + (box->y1 - dsty) * dst_stride;
d8 += (box->x1 - dstx) * 4;
bytes = box->x2 - box->x1;
bytes *= 4;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
memcpy(d8, s8, bytes);
d8 += dst_stride;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
static int
rdpFillBox_yuvalp(int ax, int ay,
void *dst, int dst_stride)
{
dst = ((char *) dst) + (ay << 8) * (dst_stride >> 8) + (ax << 8);
memset(dst, 0, 64 * 64 * 4);
return 0;
}
/******************************************************************************/
/* copy rects with no error checking
* convert ARGB32 to 64x64 linear planar YUVA */
/* http://msdn.microsoft.com/en-us/library/ff635643.aspx
* 0.299 -0.168935 0.499813
* 0.587 -0.331665 -0.418531
* 0.114 0.50059 -0.081282
y = r * 0.299000 + g * 0.587000 + b * 0.114000;
u = r * -0.168935 + g * -0.331665 + b * 0.500590;
v = r * 0.499813 + g * -0.418531 + b * -0.081282; */
/* 19595 38470 7471
-11071 -21736 32807
32756 -27429 -5327 */
static int
rdpCopyBox_a8r8g8b8_to_yuvalp(int ax, int ay,
void *src, int src_stride,
void *dst, int dst_stride,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
char *yptr;
char *uptr;
char *vptr;
char *aptr;
int *s32;
int index;
int jndex;
int kndex;
int width;
int height;
int pixel;
int a;
int r;
int g;
int b;
int y;
int u;
int v;
BoxPtr box;
dst = ((char *) dst) + (ay << 8) * (dst_stride >> 8) + (ax << 8);
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + box->y1 * src_stride;
s8 += box->x1 * 4;
d8 = ((char *) dst) + (box->y1 - ay) * 64;
d8 += box->x1 - ax;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
s32 = (int *) s8;
yptr = d8;
uptr = yptr + 64 * 64;
vptr = uptr + 64 * 64;
aptr = vptr + 64 * 64;
kndex = 0;
while (kndex < width)
{
pixel = *(s32++);
a = (pixel >> 24) & 0xff;
r = (pixel >> 16) & 0xff;
g = (pixel >> 8) & 0xff;
b = (pixel >> 0) & 0xff;
y = (r * 19595 + g * 38470 + b * 7471) >> 16;
u = (r * -11071 + g * -21736 + b * 32807) >> 16;
v = (r * 32756 + g * -27429 + b * -5327) >> 16;
y = y - 128;
y = max(y, -128);
u = max(u, -128);
v = max(v, -128);
y = min(y, 127);
u = min(u, 127);
v = min(v, 127);
*(yptr++) = y;
*(uptr++) = u;
*(vptr++) = v;
*(aptr++) = a;
kndex++;
}
d8 += 64;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
/* copy rects with no error checking */
static int
rdpCopyBox_a8r8g8b8_to_a8b8g8r8(void *src, int src_stride,
void *dst, int dst_stride,
BoxPtr rects, int num_rects)
{
char *s8;
char *d8;
int index;
int jndex;
int kndex;
int bytes;
int width;
int height;
int red;
int green;
int blue;
BoxPtr box;
unsigned int *s32;
unsigned int *d32;
for (index = 0; index < num_rects; index++)
{
box = rects + index;
s8 = ((char *) src) + box->y1 * src_stride;
s8 += box->x1 * 4;
d8 = ((char *) dst) + box->y1 * dst_stride;
d8 += box->x1 * 4;
bytes = box->x2 - box->x1;
bytes *= 4;
width = box->x2 - box->x1;
height = box->y2 - box->y1;
for (jndex = 0; jndex < height; jndex++)
{
s32 = (unsigned int *) s8;
d32 = (unsigned int *) d8;
for (kndex = 0; kndex < width; kndex++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d32 = COLOR24(red, green, blue);
s32++;
d32++;
}
d8 += dst_stride;
s8 += src_stride;
}
}
return 0;
}
/******************************************************************************/
static Bool
rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
rdpCapture0(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format, int max_rects)
{
BoxPtr prects;
BoxPtr psrc_rects;
BoxRec rect;
RegionRec reg;
char *src_rect;
char *dst_rect;
int num_regions;
int bytespp;
int num_rects;
int src_bytespp;
int dst_bytespp;
int width;
int height;
int src_offset;
int dst_offset;
int bytes;
int i;
int j;
int k;
int red;
int green;
int blue;
Bool rv;
unsigned int *s32;
unsigned short *d16;
unsigned char *d8;
LLOGLN(10, ("rdpCapture0:"));
@ -73,47 +288,320 @@ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
rdpRegionInit(&reg, &rect, 0);
rdpRegionIntersect(&reg, in_reg, &reg);
psrc_rects = 0;
num_rects = rdpLimitRects(&reg, max_rects, &psrc_rects);
if (num_rects < 1)
{
rdpRegionUninit(&reg);
return FALSE;
}
*num_out_rects = num_rects;
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * num_rects, 0);
for (i = 0; i < num_rects; i++)
{
rect = psrc_rects[i];
(*out_rects)[i] = rect;
}
if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
{
rdpCopyBox_a8r8g8b8_to_a8r8g8b8(src, src_stride, 0, 0,
dst, dst_stride, 0, 0,
psrc_rects, num_rects);
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8b8g8r8))
{
rdpCopyBox_a8r8g8b8_to_a8b8g8r8(src, src_stride,
dst, dst_stride,
psrc_rects, num_rects);
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_r5g6b5))
{
src_bytespp = 4;
dst_bytespp = 2;
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
s32 = (unsigned int *) src_rect;
d16 = (unsigned short *) dst_rect;
for (k = 0; k < width; k++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d16 = COLOR16(red, green, blue);
s32++;
d16++;
}
src_rect += src_stride;
dst_rect += dst_stride;
}
}
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a1r5g5b5))
{
src_bytespp = 4;
dst_bytespp = 2;
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
s32 = (unsigned int *) src_rect;
d16 = (unsigned short *) dst_rect;
for (k = 0; k < width; k++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d16 = COLOR15(red, green, blue);
s32++;
d16++;
}
src_rect += src_stride;
dst_rect += dst_stride;
}
}
}
else if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_r3g3b2))
{
src_bytespp = 4;
dst_bytespp = 1;
for (i = 0; i < num_rects; i++)
{
/* get rect to copy */
rect = (*out_rects)[i];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
s32 = (unsigned int *) src_rect;
d8 = (unsigned char *) dst_rect;
for (k = 0; k < width; k++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d8 = COLOR8(red, green, blue);
s32++;
d8++;
}
src_rect += src_stride;
dst_rect += dst_stride;
}
}
}
else
{
LLOGLN(0, ("rdpCapture0: unimp color conversion"));
}
rdpRegionUninit(&reg);
return rv;
}
/******************************************************************************/
/* make out_rects always multiple of 16 width and height */
static Bool
rdpCapture1(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format, int max_rects)
{
BoxPtr psrc_rects;
BoxRec rect;
RegionRec reg;
char *src_rect;
char *dst_rect;
int num_regions;
int src_bytespp;
int dst_bytespp;
int width;
int height;
int min_width;
int min_height;
int src_offset;
int dst_offset;
int index;
int jndex;
int kndex;
int red;
int green;
int blue;
int ex;
int ey;
Bool rv;
unsigned int *s32;
unsigned int *d32;
LLOGLN(10, ("rdpCapture1:"));
rv = TRUE;
min_width = RDPMIN(dst_width, src_width);
min_height = RDPMIN(dst_height, src_height);
rect.x1 = 0;
rect.y1 = 0;
rect.x2 = min_width;
rect.y2 = min_height;
rdpRegionInit(&reg, &rect, 0);
rdpRegionIntersect(&reg, in_reg, &reg);
num_regions = REGION_NUM_RECTS(&reg);
if (num_regions > max_rects)
{
num_regions = 1;
prects = rdpRegionExtents(&reg);
rdpRegionUninit(out_reg);
rdpRegionInit(out_reg, prects, 0);
psrc_rects = rdpRegionExtents(&reg);
}
else
{
prects = REGION_RECTS(&reg);
rdpRegionCopy(out_reg, &reg);
psrc_rects = REGION_RECTS(&reg);
}
if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
if (num_regions < 1)
{
bytespp = 4;
return FALSE;
}
for (i = 0; i < num_regions; i++)
*num_out_rects = num_regions;
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * num_regions * 4, 0);
index = 0;
while (index < num_regions)
{
rect = psrc_rects[index];
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
ex = ((width + 15) & ~15) - width;
if (ex != 0)
{
rect.x2 += ex;
if (rect.x2 > min_width)
{
rect.x1 -= rect.x2 - min_width;
rect.x2 = min_width;
}
if (rect.x1 < 0)
{
rect.x1 += 16;
}
}
ey = ((height + 15) & ~15) - height;
if (ey != 0)
{
rect.y2 += ey;
if (rect.y2 > min_height)
{
rect.y1 -= rect.y2 - min_height;
rect.y2 = min_height;
}
if (rect.y1 < 0)
{
rect.y1 += 16;
}
}
#if 0
if (rect.x1 < 0)
{
LLOGLN(0, ("rdpCapture1: error"));
}
if (rect.y1 < 0)
{
LLOGLN(0, ("rdpCapture1: error"));
}
if (rect.x2 > min_width)
{
LLOGLN(0, ("rdpCapture1: error"));
}
if (rect.y2 > min_height)
{
LLOGLN(0, ("rdpCapture1: error"));
}
if ((rect.x2 - rect.x1) % 16 != 0)
{
LLOGLN(0, ("rdpCapture1: error"));
}
if ((rect.y2 - rect.y1) % 16 != 0)
{
LLOGLN(0, ("rdpCapture1: error"));
}
#endif
(*out_rects)[index] = rect;
index++;
}
if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8b8g8r8))
{
src_bytespp = 4;
dst_bytespp = 4;
for (index = 0; index < num_regions; index++)
{
/* get rect to copy */
rect = prects[i];
rect = (*out_rects)[index];
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * bytespp;
src_offset = rect.y1 * src_stride + rect.x1 * src_bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * dst_bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* bytes per line */
bytes = width * bytespp;
/* copy one line at a time */
for (j = 0; j < height; j++)
for (jndex = 0; jndex < height; jndex++)
{
memcpy(dst_rect, src_rect, bytes);
s32 = (unsigned int *) src_rect;
d32 = (unsigned int *) dst_rect;
for (kndex = 0; kndex < width; kndex++)
{
SPLITCOLOR32(red, green, blue, *s32);
*d32 = COLOR24(red, green, blue);
s32++;
d32++;
}
src_rect += src_stride;
dst_rect += dst_stride;
}
@ -121,17 +609,130 @@ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
}
else
{
LLOGLN(0, ("rdpCapture0: unimp color conversion"));
LLOGLN(0, ("rdpCapture1: unimp color conversion"));
}
rdpRegionUninit(&reg);
return rv;
}
/******************************************************************************/
static Bool
rdpCapture2(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format, int max_rects)
{
int x;
int y;
int out_rect_index;
int num_rects;
int rcode;
BoxRec rect;
BoxRec extents_rect;
BoxPtr rects;
RegionRec tile_reg;
RegionRec lin_reg;
RegionRec temp_reg;
RegionPtr pin_reg;
LLOGLN(10, ("rdpCapture2:"));
*out_rects = (BoxPtr) g_malloc(sizeof(BoxRec) * RDP_MAX_TILES, 0);
if (*out_rects == NULL)
{
return FALSE;
}
out_rect_index = 0;
/* clip for smaller of 2 */
rect.x1 = 0;
rect.y1 = 0;
rect.x2 = min(dst_width, src_width);
rect.y2 = min(dst_height, src_height);
rdpRegionInit(&temp_reg, &rect, 0);
rdpRegionIntersect(&temp_reg, in_reg, &temp_reg);
/* limit the numer of rects */
num_rects = REGION_NUM_RECTS(&temp_reg);
if (num_rects > max_rects)
{
LLOGLN(10, ("rdpCapture2: too many rects"));
rdpRegionInit(&lin_reg, rdpRegionExtents(&temp_reg), 0);
pin_reg = &lin_reg;
}
else
{
LLOGLN(10, ("rdpCapture2: not too many rects"));
rdpRegionInit(&lin_reg, NullBox, 0);
pin_reg = &temp_reg;
}
extents_rect = *rdpRegionExtents(pin_reg);
y = extents_rect.y1 & ~63;
while (y < extents_rect.y2)
{
x = extents_rect.x1 & ~63;
while (x < extents_rect.x2)
{
rect.x1 = x;
rect.y1 = y;
rect.x2 = rect.x1 + 64;
rect.y2 = rect.y1 + 64;
rcode = rdpRegionContainsRect(pin_reg, &rect);
LLOGLN(10, ("rdpCapture2: rcode %d", rcode));
if (rcode != rgnOUT)
{
if (rcode == rgnPART)
{
LLOGLN(10, ("rdpCapture2: rgnPART"));
rdpFillBox_yuvalp(x, y, dst, dst_stride);
rdpRegionInit(&tile_reg, &rect, 0);
rdpRegionIntersect(&tile_reg, pin_reg, &tile_reg);
rects = REGION_RECTS(&tile_reg);
num_rects = REGION_NUM_RECTS(&tile_reg);
rdpCopyBox_a8r8g8b8_to_yuvalp(x, y,
src, src_stride,
dst, dst_stride,
rects, num_rects);
rdpRegionUninit(&tile_reg);
}
else /* rgnIN */
{
LLOGLN(10, ("rdpCapture2: rgnIN"));
rdpCopyBox_a8r8g8b8_to_yuvalp(x, y,
src, src_stride,
dst, dst_stride,
&rect, 1);
}
(*out_rects)[out_rect_index] = rect;
out_rect_index++;
if (out_rect_index >= RDP_MAX_TILES)
{
g_free(*out_rects);
*out_rects = NULL;
rdpRegionUninit(&temp_reg);
rdpRegionUninit(&lin_reg);
return FALSE;
}
}
x += 64;
}
y += 64;
}
*num_out_rects = out_rect_index;
rdpRegionUninit(&temp_reg);
rdpRegionUninit(&lin_reg);
return TRUE;
}
/**
* Copy an array of rectangles from one memory area to another
*****************************************************************************/
Bool
rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
rdpCapture(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
@ -141,7 +742,19 @@ rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
switch (mode)
{
case 0:
return rdpCapture0(in_reg, out_reg,
return rdpCapture0(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
dst_stride, dst_format, 15);
case 1:
return rdpCapture1(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
dst_stride, dst_format, 15);
case 2:
return rdpCapture2(clientCon, in_reg, out_rects, num_out_rects,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
@ -150,5 +763,5 @@ rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
LLOGLN(0, ("rdpCapture: unimp mode"));
break;
}
return TRUE;
return FALSE;
}

@ -19,9 +19,9 @@
*/
Bool
rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
rdpCapture(rdpClientCon *clientCon,
RegionPtr in_reg, BoxPtr *out_rects, int *num_out_rects,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format,
int mode);
int dst_stride, int dst_format, int mode);

@ -50,21 +50,6 @@ Client connection to xrdp
#define LTOUI32(_in) ((unsigned int)(_in))
#define COLOR8(r, g, b) \
((((r) >> 5) << 0) | (((g) >> 5) << 3) | (((b) >> 6) << 6))
#define COLOR15(r, g, b) \
((((r) >> 3) << 10) | (((g) >> 3) << 5) | (((b) >> 3) << 0))
#define COLOR16(r, g, b) \
((((r) >> 3) << 11) | (((g) >> 2) << 5) | (((b) >> 3) << 0))
#define COLOR24(r, g, b) \
((((r) >> 0) << 0) | (((g) >> 0) << 8) | (((b) >> 0) << 16))
#define SPLITCOLOR32(r, g, b, c) \
do { \
r = ((c) >> 16) & 0xff; \
g = ((c) >> 8) & 0xff; \
b = (c) & 0xff; \
} while (0)
#define USE_MAX_OS_BYTES 1
#define MAX_OS_BYTES (16 * 1024 * 1024)
@ -107,6 +92,9 @@ static int g_rdp_opcodes[16] =
0xff /* GXset 0xf 1 */
};
static int
rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon);
/******************************************************************************/
static int
rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
@ -144,6 +132,15 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
AddEnabledDevice(clientCon->sck);
}
#if 0
if (dev->clientConTail != NULL)
{
rdpClientConDisconnect(dev, dev->clientConTail);
dev->clientConHead = NULL;
dev->clientConTail = NULL;
}
#endif
if (dev->clientConTail == NULL)
{
LLOGLN(0, ("rdpClientConGotConnection: adding only clientCon"));
@ -274,6 +271,11 @@ rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
}
rdpRegionDestroy(clientCon->dirtyRegion);
rdpRegionDestroy(clientCon->shmRegion);
if (clientCon->updateTimer != NULL)
{
TimerCancel(clientCon->updateTimer);
TimerFree(clientCon->updateTimer);
}
g_free(clientCon);
return 0;
}
@ -533,6 +535,8 @@ rdpClientConProcessMsgVersion(rdpPtr dev, rdpClientCon *clientCon,
return 0;
}
#define LALIGN(_num, _po2) ((_num + ((_po2) - 1)) & ~((_po2) - 1))
/******************************************************************************/
/*
this from miScreenInit
@ -549,31 +553,37 @@ rdpClientConProcessScreenSizeMsg(rdpPtr dev, rdpClientCon *clientCon,
int bytes;
Bool ok;
LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: set width %d height %d bpp %d",
width, height, bpp));
LLOGLN(0, ("rdpClientConProcessScreenSizeMsg: set width %d height %d "
"bpp %d", width, height, bpp));
clientCon->rdp_width = width;
clientCon->rdp_height = height;
clientCon->rdp_bpp = bpp;
clientCon->cap_width = width;
clientCon->cap_height = height;
if (bpp < 15)
{
clientCon->rdp_Bpp = 1;
clientCon->rdp_Bpp_mask = 0xff;
clientCon->rdp_format = PIXMAN_r3g3b2;
}
else if (bpp == 15)
{
clientCon->rdp_Bpp = 2;
clientCon->rdp_Bpp_mask = 0x7fff;
clientCon->rdp_format = XRDP_a1r5g5b5;
}
else if (bpp == 16)
{
clientCon->rdp_Bpp = 2;
clientCon->rdp_Bpp_mask = 0xffff;
clientCon->rdp_format = XRDP_r5g6b5;
}
else if (bpp > 16)
{
clientCon->rdp_Bpp = 4;
clientCon->rdp_Bpp_mask = 0xffffff;
clientCon->rdp_format = XRDP_a8r8g8b8;
}
if (clientCon->shmemptr != 0)
@ -655,12 +665,13 @@ rdpClientConProcessMsgClientInput(rdpPtr dev, rdpClientCon *clientCon)
}
else if (msg == 300) /* resize desktop */
{
rdpClientConProcessScreenSizeMsg(dev, clientCon, param1, param2, param3);
rdpClientConProcessScreenSizeMsg(dev, clientCon, param1,
param2, param3);
}
else if (msg == 301) /* version */
{
rdpClientConProcessMsgVersion(dev, clientCon,
param1, param2, param3, param4);
param1, param2, param3, param4);
}
else
{
@ -697,6 +708,32 @@ rdpClientConProcessMsgClientInfo(rdpPtr dev, rdpClientCon *clientCon)
i1 = clientCon->client_info.offscreen_cache_entries;
LLOGLN(0, (" offscreen entries %d", i1));
if (clientCon->client_info.capture_format != 0)
{
clientCon->rdp_format = clientCon->client_info.capture_format;
}
if (clientCon->client_info.capture_code == 2) /* RFX */
{
LLOGLN(0, ("rdpClientConProcessMsgClientInfo: got RFX capture"));
clientCon->cap_width = LALIGN(clientCon->rdp_width, 64);
clientCon->cap_height = LALIGN(clientCon->rdp_height, 64);
LLOGLN(0, (" cap_width %d cap_height %d",
clientCon->cap_width, clientCon->cap_height));
if (clientCon->shmemptr != 0)
{
shmdt(clientCon->shmemptr);
}
bytes = clientCon->cap_width * clientCon->cap_height *
clientCon->rdp_Bpp;
clientCon->shmemid = shmget(IPC_PRIVATE, bytes, IPC_CREAT | 0777);
clientCon->shmemptr = shmat(clientCon->shmemid, 0, 0);
shmctl(clientCon->shmemid, IPC_RMID, NULL);
LLOGLN(0, ("rdpClientConProcessMsgClientInfo: shmemid %d shmemptr %p "
"bytes %d", clientCon->shmemid, clientCon->shmemptr, bytes));
clientCon->shmem_lineBytes = clientCon->rdp_Bpp * clientCon->cap_width;
}
if (clientCon->client_info.offscreen_support_level > 0)
{
if (clientCon->client_info.offscreen_cache_entries > 0)
@ -1878,19 +1915,29 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
static int
rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
struct image_data *id,
RegionPtr dirtyReg, RegionPtr copyReg)
RegionPtr dirtyReg,
BoxPtr copyRects, int numCopyRects)
{
int index;
int size;
int num_rects_d;
int num_rects_c;
short x;
short y;
short cx;
short cy;
struct stream *s;
BoxRec box;
rdpClientConBeginUpdate(dev, clientCon);
num_rects_d = REGION_NUM_RECTS(dirtyReg);
num_rects_c = REGION_NUM_RECTS(copyReg);
num_rects_c = numCopyRects;
if ((num_rects_c < 1) || (num_rects_d < 1))
{
LLOGLN(0, ("rdpClientConSendPaintRectShmEx: nothing to send"));
return 0;
}
size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8;
size += 4 + 4 + 4 + 4 + 2 + 2;
rdpClientConPreCheck(dev, clientCon, size);
@ -1904,20 +1951,28 @@ rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
for (index = 0; index < num_rects_d; index++)
{
box = REGION_RECTS(dirtyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
x = box.x1;
y = box.y1;
cx = box.x2 - box.x1;
cy = box.y2 - box.y1;
out_uint16_le(s, x);
out_uint16_le(s, y);
out_uint16_le(s, cx);
out_uint16_le(s, cy);
}
out_uint16_le(s, num_rects_c);
for (index = 0; index < num_rects_c; index++)
{
box = REGION_RECTS(copyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
box = copyRects[index];
x = box.x1;
y = box.y1;
cx = box.x2 - box.x1;
cy = box.y2 - box.y1;
out_uint16_le(s, x);
out_uint16_le(s, y);
out_uint16_le(s, cx);
out_uint16_le(s, cy);
}
out_uint32_le(s, 0);
@ -1925,8 +1980,8 @@ rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
out_uint32_le(s, clientCon->rect_id);
out_uint32_le(s, id->shmem_id);
out_uint32_le(s, id->shmem_offset);
out_uint16_le(s, clientCon->rdp_width);
out_uint16_le(s, clientCon->rdp_height);
out_uint16_le(s, clientCon->cap_width);
out_uint16_le(s, clientCon->cap_height);
rdpClientConEndUpdate(dev, clientCon);
@ -1938,17 +1993,23 @@ static CARD32
rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{
rdpClientCon *clientCon;
RegionRec reg;
BoxPtr rects;
int num_rects;
struct image_data id;
LLOGLN(10, ("rdpDeferredUpdateCallback:"));
clientCon = (rdpClientCon *) arg;
if (clientCon->rect_id != clientCon->rect_id_ack)
if ((clientCon->rect_id > clientCon->rect_id_ack) ||
/* do not allow captures until we have the client_info */
clientCon->client_info.size == 0)
{
LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual"));
LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual rect_id %d "
"rect_id_ack %d",
clientCon->rect_id, clientCon->rect_id_ack));
clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
rdpDeferredUpdateCallback, clientCon);
rdpDeferredUpdateCallback,
clientCon);
return 0;
}
else
@ -1961,17 +2022,29 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
id.width, id.height));
clientCon->updateSchedualed = FALSE;
rdpRegionInit(&reg, NullBox, 0);
rdpCapture(clientCon->dirtyRegion, &reg,
id.pixels, id.width, id.height,
id.lineBytes, XRDP_a8r8g8b8,
id.shmem_pixels, clientCon->rdp_width, clientCon->rdp_height,
clientCon->rdp_width * clientCon->rdp_Bpp , XRDP_a8r8g8b8, 0);
rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
clientCon->dirtyRegion, &reg);
rects = 0;
num_rects = 0;
LLOGLN(10, ("rdpDeferredUpdateCallback: capture_code %d",
clientCon->client_info.capture_code));
if (rdpCapture(clientCon, clientCon->dirtyRegion, &rects, &num_rects,
id.pixels, id.width, id.height,
id.lineBytes, XRDP_a8r8g8b8, id.shmem_pixels,
clientCon->cap_width, clientCon->cap_height,
clientCon->cap_width * clientCon->rdp_Bpp,
clientCon->rdp_format, clientCon->client_info.capture_code))
{
LLOGLN(10, ("rdpDeferredUpdateCallback: num_rects %d", num_rects));
rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
clientCon->dirtyRegion,
rects, num_rects);
g_free(rects);
}
else
{
LLOGLN(0, ("rdpDeferredUpdateCallback: rdpCapture failed"));
}
rdpRegionDestroy(clientCon->dirtyRegion);
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
rdpRegionUninit(&reg);
return 0;
}

@ -79,6 +79,9 @@ struct _rdpClientCon
int rdp_Bpp_mask;
int rdp_width;
int rdp_height;
int rdp_format; /* XRDP_a8r8g8b8, XRDP_r5g6b5, ... */
int cap_width;
int cap_height;
int rdpIndex; /* current os target */
@ -88,8 +91,6 @@ struct _rdpClientCon
struct font_cache font_cache[12][256];
int font_stamp;
RegionPtr dirtyRegion;
struct xrdp_client_info client_info;
char *shmemptr;
@ -102,6 +103,8 @@ struct _rdpClientCon
OsTimerPtr updateTimer;
int updateSchedualed; /* boolean */
RegionPtr dirtyRegion;
struct _rdpClientCon *next;
};

@ -39,11 +39,18 @@ cursor
#include <cursor.h>
#include <cursorstr.h>
#include <X11/Xarch.h>
#include "rdp.h"
#include "rdpMain.h"
#include "rdpDraw.h"
#include "rdpClientCon.h"
#ifndef X_BYTE_ORDER
#warning X_BYTE_ORDER not defined
#endif
#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
/* Copied from Xvnc/lib/font/util/utilbitmap.c */
static unsigned char g_reverse_byte[0x100] =
{
@ -80,6 +87,7 @@ static unsigned char g_reverse_byte[0x100] =
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
#endif
/******************************************************************************/
#define LOG_LEVEL 1

@ -47,14 +47,6 @@ rdp module main
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define XRDP_DRIVER_NAME "XORGXRDP"
#define XRDP_NAME "XORGXRDP"
#define XRDP_VERSION 1000
#define PACKAGE_VERSION_MAJOR 1
#define PACKAGE_VERSION_MINOR 0
#define PACKAGE_VERSION_PATCHLEVEL 0
static Bool g_initialised = FALSE;
/*****************************************************************************/
@ -95,7 +87,7 @@ xorgxrdpDownDown(ScreenPtr pScreen)
static MODULESETUPPROTO(xorgxrdpSetup);
static XF86ModuleVersionInfo RDPVersRec =
{
XRDP_DRIVER_NAME,
XRDP_MODULE_NAME,
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,

@ -0,0 +1,138 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SIMD function asign
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
#include <xf86_OSproc.h>
#include "rdp.h"
#include "rdpXv.h"
/* use simd, run time */
int g_simd_use_accel = 1;
/* use simd, compile time, if zero, g_simd_use_accel does not matter */
#if !defined(SIMD_USE_ACCEL)
#define SIMD_USE_ACCEL 0
#endif
#if SIMD_USE_ACCEL
#if defined(__x86_64__) || defined(__AMD64__) || defined (_M_AMD64)
#include "amd64/funcs_amd64.h"
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
#include "x86/funcs_x86.h"
#endif
#endif
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/*****************************************************************************/
Bool
rdpSimdInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
{
rdpPtr dev;
dev = XRDPPTR(pScrn);
/* assign functions */
LLOGLN(0, ("rdpSimdInit: assigning yuv functions"));
#if SIMD_USE_ACCEL
if (g_simd_use_accel)
{
#if defined(__x86_64__) || defined(__AMD64__) || defined (_M_AMD64)
int ax, bx, cx, dx;
cpuid_amd64(1, 0, &ax, &bx, &cx, &dx);
LLOGLN(0, ("rdpSimdInit: cpuid ax 1 cx 0 return ax 0x%8.8x bx "
"0x%8.8x cx 0x%8.8x dx 0x%8.8x", ax, bx, cx, dx));
if (dx & (1 << 26)) /* SSE 2 */
{
dev->yv12_to_rgb32 = yv12_to_rgb32_amd64_sse2;
dev->i420_to_rgb32 = i420_to_rgb32_amd64_sse2;
dev->yuy2_to_rgb32 = yuy2_to_rgb32_amd64_sse2;
dev->uyvy_to_rgb32 = uyvy_to_rgb32_amd64_sse2;
LLOGLN(0, ("rdpSimdInit: sse2 amd64 yuv functions assigned"));
}
else
{
dev->yv12_to_rgb32 = YV12_to_RGB32;
dev->i420_to_rgb32 = I420_to_RGB32;
dev->yuy2_to_rgb32 = YUY2_to_RGB32;
dev->uyvy_to_rgb32 = UYVY_to_RGB32;
LLOGLN(0, ("rdpSimdInit: warning, c yuv functions assigned"));
}
#elif defined(__x86__) || defined(_M_IX86) || defined(__i386__)
int ax, bx, cx, dx;
cpuid_x86(1, 0, &ax, &bx, &cx, &dx);
LLOGLN(0, ("rdpSimdInit: cpuid ax 1 cx 0 return ax 0x%8.8x bx "
"0x%8.8x cx 0x%8.8x dx 0x%8.8x", ax, bx, cx, dx));
if (dx & (1 << 26)) /* SSE 2 */
{
dev->yv12_to_rgb32 = yv12_to_rgb32_x86_sse2;
dev->i420_to_rgb32 = i420_to_rgb32_x86_sse2;
dev->yuy2_to_rgb32 = yuy2_to_rgb32_x86_sse2;
dev->uyvy_to_rgb32 = uyvy_to_rgb32_x86_sse2;
LLOGLN(0, ("rdpSimdInit: sse2 x86 yuv functions assigned"));
}
else
{
dev->yv12_to_rgb32 = YV12_to_RGB32;
dev->i420_to_rgb32 = I420_to_RGB32;
dev->yuy2_to_rgb32 = YUY2_to_RGB32;
dev->uyvy_to_rgb32 = UYVY_to_RGB32;
LLOGLN(0, ("rdpSimdInit: warning, c yuv functions assigned"));
}
#else
dev->yv12_to_rgb32 = YV12_to_RGB32;
dev->i420_to_rgb32 = I420_to_RGB32;
dev->yuy2_to_rgb32 = YUY2_to_RGB32;
dev->uyvy_to_rgb32 = UYVY_to_RGB32;
LLOGLN(0, ("rdpSimdInit: warning, c yuv functions assigned"));
#endif
}
else
{
dev->yv12_to_rgb32 = YV12_to_RGB32;
dev->i420_to_rgb32 = I420_to_RGB32;
dev->yuy2_to_rgb32 = YUY2_to_RGB32;
dev->uyvy_to_rgb32 = UYVY_to_RGB32;
LLOGLN(0, ("rdpSimdInit: warning, c yuv functions assigned"));
}
#else
dev->yv12_to_rgb32 = YV12_to_RGB32;
dev->i420_to_rgb32 = I420_to_RGB32;
dev->yuy2_to_rgb32 = YUY2_to_RGB32;
dev->uyvy_to_rgb32 = UYVY_to_RGB32;
LLOGLN(0, ("rdpSimdInit: warning, c yuv functions assigned"));
#endif
return 1;
}

@ -0,0 +1,34 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SIMD function asign
*/
#ifndef __RDPSIMD_H
#define __RDPSIMD_H
#include <xorg-server.h>
#include <xorgVersion.h>
#include <xf86.h>
Bool
rdpSimdInit(ScreenPtr pScreen, ScrnInfoPtr pScrn);
#endif

@ -0,0 +1,678 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
XVideo
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* this should be before all X11 .h files */
#include <xorg-server.h>
#include <xorgVersion.h>
/* all driver need this */
#include <xf86.h>
#include <xf86_OSproc.h>
#include <xf86xv.h>
#include <X11/extensions/Xv.h>
#include <fourcc.h>
#include <fb.h>
#include "rdp.h"
#include "rdpMisc.h"
#include "rdpReg.h"
#include "rdpClientCon.h"
#define LOG_LEVEL 1
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define T_NUM_ENCODINGS 1
static XF86VideoEncodingRec g_xrdpVidEncodings[T_NUM_ENCODINGS] =
{ { 0, "XV_IMAGE", 2046, 2046, { 1, 1 } } };
#define T_NUM_FORMATS 1
static XF86VideoFormatRec g_xrdpVidFormats[T_NUM_FORMATS] =
{ { 0, TrueColor } };
/* YV12
I420
12 bpp planar
YUV 4:2:0 8 bit Y plane followed by 8 bit 2x2 subsampled
U and V planes. */
/* YUY2
UYVY
16 bpp packed
YUV 4:2:2 Y sample at every pixel, U and V sampled at
every second pixel */
/* XVIMAGE_YV12 FOURCC_YV12 0x32315659 */
/* XVIMAGE_I420 FOURCC_I420 0x30323449 */
/* XVIMAGE_YUY2 FOURCC_YUY2 0x32595559 */
/* XVIMAGE_UYVY FOURCC_UYVY 0x59565955 */
static XF86ImageRec g_xrdpVidImages[] =
{ XVIMAGE_YV12, XVIMAGE_I420, XVIMAGE_YUY2, XVIMAGE_UYVY };
#define T_MAX_PORTS 1
/*****************************************************************************/
static int
xrdpVidPutVideo(ScrnInfoPtr pScrn, short vid_x, short vid_y,
short drw_x, short drw_y, short vid_w, short vid_h,
short drw_w, short drw_h, RegionPtr clipBoxes,
pointer data, DrawablePtr pDraw)
{
LLOGLN(0, ("xrdpVidPutVideo:"));
return Success;
}
/*****************************************************************************/
static int
xrdpVidPutStill(ScrnInfoPtr pScrn, short vid_x, short vid_y,
short drw_x, short drw_y, short vid_w, short vid_h,
short drw_w, short drw_h, RegionPtr clipBoxes,
pointer data, DrawablePtr pDraw)
{
LLOGLN(0, ("xrdpVidPutStill:"));
return Success;
}
/*****************************************************************************/
static int
xrdpVidGetVideo(ScrnInfoPtr pScrn, short vid_x, short vid_y,
short drw_x, short drw_y, short vid_w, short vid_h,
short drw_w, short drw_h, RegionPtr clipBoxes,
pointer data, DrawablePtr pDraw)
{
LLOGLN(0, ("xrdpVidGetVideo:"));
return Success;
}
/*****************************************************************************/
static int
xrdpVidGetStill(ScrnInfoPtr pScrn, short vid_x, short vid_y,
short drw_x, short drw_y, short vid_w, short vid_h,
short drw_w, short drw_h, RegionPtr clipBoxes,
pointer data, DrawablePtr pDraw)
{
LLOGLN(0, ("FBDevTIVidGetStill:"));
return Success;
}
/*****************************************************************************/
static void
xrdpVidStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup)
{
LLOGLN(0, ("xrdpVidStopVideo:"));
}
/*****************************************************************************/
static int
xrdpVidSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
INT32 value, pointer data)
{
LLOGLN(0, ("xrdpVidSetPortAttribute:"));
return Success;
}
/*****************************************************************************/
static int
xrdpVidGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
INT32 *value, pointer data)
{
LLOGLN(0, ("xrdpVidGetPortAttribute:"));
return Success;
}
/*****************************************************************************/
static void
xrdpVidQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
short vid_w, short vid_h, short drw_w, short drw_h,
unsigned int *p_w, unsigned int *p_h, pointer data)
{
LLOGLN(0, ("xrdpVidQueryBestSize:"));
}
/*****************************************************************************/
int
YV12_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs)
{
int size_total;
int y;
int u;
int v;
int c;
int d;
int e;
int r;
int g;
int b;
int t;
int i;
int j;
size_total = width * height;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
y = yuvs[j * width + i];
u = yuvs[(j / 2) * (width / 2) + (i / 2) + size_total];
v = yuvs[(j / 2) * (width / 2) + (i / 2) + size_total + (size_total / 4)];
c = y - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
}
}
return 0;
}
/*****************************************************************************/
int
I420_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs)
{
int size_total;
int y;
int u;
int v;
int c;
int d;
int e;
int r;
int g;
int b;
int t;
int i;
int j;
size_total = width * height;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
y = yuvs[j * width + i];
v = yuvs[(j / 2) * (width / 2) + (i / 2) + size_total];
u = yuvs[(j / 2) * (width / 2) + (i / 2) + size_total + (size_total / 4)];
c = y - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
}
}
return 0;
}
/*****************************************************************************/
int
YUY2_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs)
{
int y1;
int y2;
int u;
int v;
int c;
int d;
int e;
int r;
int g;
int b;
int t;
int i;
int j;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
y1 = *(yuvs++);
v = *(yuvs++);
y2 = *(yuvs++);
u = *(yuvs++);
c = y1 - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
i++;
c = y2 - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
}
}
return 0;
}
/*****************************************************************************/
int
UYVY_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs)
{
int y1;
int y2;
int u;
int v;
int c;
int d;
int e;
int r;
int g;
int b;
int t;
int i;
int j;
for (j = 0; j < height; j++)
{
for (i = 0; i < width; i++)
{
v = *(yuvs++);
y1 = *(yuvs++);
u = *(yuvs++);
y2 = *(yuvs++);
c = y1 - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
i++;
c = y2 - 16;
d = u - 128;
e = v - 128;
t = (298 * c + 409 * e + 128) >> 8;
b = RDPCLAMP(t, 0, 255);
t = (298 * c - 100 * d - 208 * e + 128) >> 8;
g = RDPCLAMP(t, 0, 255);
t = (298 * c + 516 * d + 128) >> 8;
r = RDPCLAMP(t, 0, 255);
rgbs[j * width + i] = (r << 16) | (g << 8) | b;
}
}
return 0;
}
#if 0
/*****************************************************************************/
static int
stretch_RGB32_RGB32(int *src, int src_width, int src_height,
int src_x, int src_y, int src_w, int src_h,
int *dst, int dst_w, int dst_h)
{
int mwidth;
int mheight;
int index;
mwidth = RDPMIN(src_width, dst_w);
mheight = RDPMIN(src_height, dst_h);
for (index = 0; index < mheight; index++)
{
g_memcpy(dst, src, mwidth * 4);
src += src_width;
dst += dst_w;
}
return 0;
}
#endif
/*****************************************************************************/
static int
stretch_RGB32_RGB32(int *src, int src_width, int src_height,
int src_x, int src_y, int src_w, int src_h,
int *dst, int dst_w, int dst_h)
{
int index;
int jndex;
int lndex;
int last_lndex;
int oh;
int ih;
int ov;
int iv;
int pix;
int *src32;
int *dst32;
LLOGLN(10, ("stretch_RGB32_RGB32: oh 0x%8.8x ov 0x%8.8x", oh, ov));
oh = (src_w << 16) / dst_w;
ov = (src_h << 16) / dst_h;
iv = ov;
lndex = src_y;
last_lndex = -1;
for (index = 0; index < dst_h; index++)
{
if (lndex == last_lndex)
{
/* repeat line */
dst32 = dst + index * dst_w;
src32 = dst32 - dst_w;
g_memcpy(dst32, src32, dst_w * 4);
}
else
{
ih = oh;
src32 = src + lndex * src_width + src_x;
pix = *src32;
dst32 = dst + index * dst_w;
for (jndex = 0; jndex < dst_w; jndex++)
{
*dst32 = pix;
while (ih > (1 << 16) - 1)
{
ih -= 1 << 16;
src32++;
}
pix = *src32;
ih += oh;
dst32++;
}
}
last_lndex = lndex;
while (iv > (1 << 16) - 1)
{
iv -= 1 << 16;
lndex++;
}
iv += ov;
}
LLOGLN(10, ("stretch_RGB32_RGB32: out"));
return 0;
}
/******************************************************************************/
/* returns error */
static CARD32
rdpDeferredXvCleanup(OsTimerPtr timer, CARD32 now, pointer arg)
{
rdpPtr dev;
LLOGLN(0, ("rdpDeferredXvCleanup:"));
dev = (rdpPtr) arg;
dev->xv_timer_schedualed = 0;
dev->xv_data_bytes = 0;
g_free(dev->xv_data);
dev->xv_data = 0;
return 0;
}
/*****************************************************************************/
/* see hw/xfree86/common/xf86xv.c for info */
static int
xrdpVidPutImage(ScrnInfoPtr pScrn,
short src_x, short src_y, short drw_x, short drw_y,
short src_w, short src_h, short drw_w, short drw_h,
int format, unsigned char* buf,
short width, short height,
Bool sync, RegionPtr clipBoxes,
pointer data, DrawablePtr dst)
{
rdpPtr dev;
int *rgborg32;
int *rgbend32;
int index;
int error;
GCPtr tempGC;
LLOGLN(10, ("xrdpVidPutImage: format 0x%8.8x", format));
LLOGLN(10, ("xrdpVidPutImage: src_x %d srcy_y %d", src_x, src_y));
dev = XRDPPTR(pScrn);
if (dev->xv_timer_schedualed)
{
TimerCancel(dev->xv_timer);
dev->xv_timer = TimerSet(dev->xv_timer, 0, 2000,
rdpDeferredXvCleanup, dev);
}
else
{
dev->xv_timer_schedualed = 1;
dev->xv_timer = TimerSet(dev->xv_timer, 0, 2000,
rdpDeferredXvCleanup, dev);
}
index = width * height * 4 + drw_w * drw_h * 4 + 64;
if (index > dev->xv_data_bytes)
{
g_free(dev->xv_data);
dev->xv_data = g_malloc(index, 0);
if (dev->xv_data == NULL)
{
LLOGLN(0, ("xrdpVidPutImage: memory alloc error"));
dev->xv_data_bytes = 0;
return Success;
}
dev->xv_data_bytes = index;
}
rgborg32 = (int *) RDPALIGN(dev->xv_data, 16);
rgbend32 = rgborg32 + width * height;
rgbend32 = (int *) RDPALIGN(rgbend32, 16);
error = 0;
switch (format)
{
case FOURCC_YV12:
LLOGLN(10, ("xrdpVidPutImage: FOURCC_YV12"));
error = dev->yv12_to_rgb32(buf, width, height, rgborg32);
break;
case FOURCC_I420:
LLOGLN(10, ("xrdpVidPutImage: FOURCC_I420"));
error = dev->i420_to_rgb32(buf, width, height, rgborg32);
break;
case FOURCC_YUY2:
LLOGLN(10, ("xrdpVidPutImage: FOURCC_YUY2"));
error = dev->yuy2_to_rgb32(buf, width, height, rgborg32);
break;
case FOURCC_UYVY:
LLOGLN(10, ("xrdpVidPutImage: FOURCC_UYVY"));
error = dev->uyvy_to_rgb32(buf, width, height, rgborg32);
break;
default:
LLOGLN(0, ("xrdpVidPutImage: unknown format 0x%8.8x", format));
return Success;
}
if (error != 0)
{
return Success;
}
error = stretch_RGB32_RGB32(rgborg32, width, height,
src_x, src_y, src_w, src_h,
rgbend32, drw_w, drw_h);
if (error != 0)
{
return Success;
}
tempGC = GetScratchGC(dst->depth, pScrn->pScreen);
if (tempGC != NULL)
{
ValidateGC(dst, tempGC);
(*tempGC->ops->PutImage)(dst, tempGC, 24,
drw_x - dst->x, drw_y - dst->y,
drw_w, drw_h, 0, ZPixmap, (char*)rgbend32);
FreeScratchGC(tempGC);
}
return Success;
}
/*****************************************************************************/
static int
xrdpVidQueryImageAttributes(ScrnInfoPtr pScrn, int id,
unsigned short *w, unsigned short *h,
int *pitches, int *offsets)
{
int size, tmp;
LLOGLN(10, ("xrdpVidQueryImageAttributes:"));
/* this is same code as all drivers currently have */
if (*w > 2046)
{
*w = 2046;
}
if (*h > 2046)
{
*h = 2046;
}
/* make w multiple of 4 so that resizing works properly */
*w = (*w + 3) & ~3;
if (offsets != NULL)
{
offsets[0] = 0;
}
switch (id)
{
case FOURCC_YV12:
case FOURCC_I420:
/* make h be even */
*h = (*h + 1) & ~1;
/* make w be multiple of 4 (ie. pad it) */
size = (*w + 3) & ~3;
/* width of a Y row => width of image */
if (pitches != NULL)
{
pitches[0] = size;
}
/* offset of U plane => w * h */
size *= *h;
if (offsets != NULL)
{
offsets[1] = size;
}
/* width of U, V row => width / 2 */
tmp = ((*w >> 1) + 3) & ~3;
if (pitches != NULL)
{
pitches[1] = pitches[2] = tmp;
}
/* offset of V => Y plane + U plane (w * h + w / 2 * h / 2) */
tmp *= (*h >> 1);
size += tmp;
if (offsets != NULL)
{
offsets[2] = size;
}
size += tmp;
break;
case FOURCC_YUY2:
case FOURCC_UYVY:
size = (*w) * 2;
if (pitches != NULL)
{
pitches[0] = size;
}
size *= *h;
break;
default:
LLOGLN(0, ("xrdpVidQueryImageAttributes: Unsupported image"));
return 0;
}
LLOGLN(10, ("xrdpVidQueryImageAttributes: finished size %d id 0x%x", size, id));
return size;
}
/*****************************************************************************/
Bool
rdpXvInit(ScreenPtr pScreen, ScrnInfoPtr pScrn)
{
XF86VideoAdaptorPtr adaptor;
DevUnion* pDevUnion;
int bytes;
adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
if (adaptor == 0)
{
LLOGLN(0, ("rdpXvInit: xf86XVAllocateVideoAdaptorRec failed"));
return 0;
}
adaptor->type = XvInputMask | XvImageMask | XvVideoMask | XvStillMask | XvWindowMask | XvPixmapMask;
//adaptor->flags = VIDEO_NO_CLIPPING;
//adaptor->flags = VIDEO_CLIP_TO_VIEWPORT;
adaptor->flags = 0;
adaptor->name = XRDP_MODULE_NAME " XVideo Adaptor";
adaptor->nEncodings = T_NUM_ENCODINGS;
adaptor->pEncodings = &(g_xrdpVidEncodings[0]);
adaptor->nFormats = T_NUM_FORMATS;
adaptor->pFormats = &(g_xrdpVidFormats[0]);
adaptor->pFormats[0].depth = pScrn->depth;
LLOGLN(0, ("rdpXvInit: depth %d", pScrn->depth));
adaptor->nImages = sizeof(g_xrdpVidImages) / sizeof(XF86ImageRec);
adaptor->pImages = g_xrdpVidImages;
adaptor->nAttributes = 0;
adaptor->pAttributes = 0;
adaptor->nPorts = T_MAX_PORTS;
bytes = sizeof(DevUnion) * T_MAX_PORTS;
pDevUnion = (DevUnion*) g_malloc(bytes, 1);
adaptor->pPortPrivates = pDevUnion;
adaptor->PutVideo = xrdpVidPutVideo;
adaptor->PutStill = xrdpVidPutStill;
adaptor->GetVideo = xrdpVidGetVideo;
adaptor->GetStill = xrdpVidGetStill;
adaptor->StopVideo = xrdpVidStopVideo;
adaptor->SetPortAttribute = xrdpVidSetPortAttribute;
adaptor->GetPortAttribute = xrdpVidGetPortAttribute;
adaptor->QueryBestSize = xrdpVidQueryBestSize;
adaptor->PutImage = xrdpVidPutImage;
adaptor->QueryImageAttributes = xrdpVidQueryImageAttributes;
if (!xf86XVScreenInit(pScreen, &adaptor, 1))
{
LLOGLN(0, ("rdpXvInit: xf86XVScreenInit failed"));
return 0;
}
xf86XVFreeVideoAdaptorRec(adaptor);
return 1;
}

@ -0,0 +1,43 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
XVideo
*/
#ifndef __RDPXV_H
#define __RDPXV_H
#include <xorg-server.h>
#include <xorgVersion.h>
#include <xf86.h>
Bool
rdpXvInit(ScreenPtr pScreen, ScrnInfoPtr pScrn);
int
YV12_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs);
int
I420_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs);
int
YUY2_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs);
int
UYVY_to_RGB32(unsigned char *yuvs, int width, int height, int *rgbs);
#endif

@ -0,0 +1,39 @@
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
;int
;cpuid_x86(int eax_in, int ecx_in, int *eax, int *ebx, int *ecx, int *edx)
PROC cpuid_x86
; save registers
push ebx
push ecx
push edx
push edi
; cpuid
mov eax, [esp + 20]
mov ecx, [esp + 24]
cpuid
mov edi, [esp + 28]
mov [edi], eax
mov edi, [esp + 32]
mov [edi], ebx
mov edi, [esp + 36]
mov [edi], ecx
mov edi, [esp + 40]
mov [edi], edx
mov eax, 0
; restore registers
pop edi
pop edx
pop ecx
pop ebx
ret;
align 16

@ -0,0 +1,39 @@
/*
Copyright 2014 Jay Sorg
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
x86 asm files
*/
#ifndef __FUNCS_X86_H
#define __FUNCS_X86_H
int
cpuid_x86(int eax_in, int ecx_in, int *eax, int *ebx, int *ecx, int *edx);
int
yv12_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
i420_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
yuy2_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
int
uyvy_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs);
#endif

@ -0,0 +1,243 @@
;
;Copyright 2014 Jay Sorg
;
;Permission to use, copy, modify, distribute, and sell this software and its
;documentation for any purpose is hereby granted without fee, provided that
;the above copyright notice appear in all copies and that both that
;copyright notice and this permission notice appear in supporting
;documentation.
;
;The above copyright notice and this permission notice shall be included in
;all copies or substantial portions of the Software.
;
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
;AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;I420 to RGB32
;x86 SSE2 32 bit
;
; RGB to YUV
; 0.299 0.587 0.114
; -0.14713 -0.28886 0.436
; 0.615 -0.51499 -0.10001
; YUV to RGB
; 1 0 1.13983
; 1 -0.39465 -0.58060
; 1 2.03211 0
; shift left 12
; 4096 0 4669
; 4096 -1616 -2378
; 4096 9324 0
SECTION .data
align 16
c128 times 8 dw 128
c4669 times 8 dw 4669
c1616 times 8 dw 1616
c2378 times 8 dw 2378
c9324 times 8 dw 9324
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
do8_uv:
; v
movd xmm1, [ebx] ; 4 at a time
lea ebx, [ebx + 4]
punpcklbw xmm1, xmm1
pxor xmm6, xmm6
punpcklbw xmm1, xmm6
movdqa xmm7, [c128]
psubw xmm1, xmm7
psllw xmm1, 4
; u
movd xmm2, [edx] ; 4 at a time
lea edx, [edx + 4]
punpcklbw xmm2, xmm2
punpcklbw xmm2, xmm6
psubw xmm2, xmm7
psllw xmm2, 4
do8:
; y
movq xmm0, [esi] ; 8 at a time
lea esi, [esi + 8]
pxor xmm6, xmm6
punpcklbw xmm0, xmm6
; r = y + hiword(4669 * (v << 4))
movdqa xmm4, [c4669]
pmulhw xmm4, xmm1
movdqa xmm3, xmm0
paddw xmm3, xmm4
; g = y - hiword(1616 * (u << 4)) - hiword(2378 * (v << 4))
movdqa xmm5, [c1616]
pmulhw xmm5, xmm2
movdqa xmm6, [c2378]
pmulhw xmm6, xmm1
movdqa xmm4, xmm0
psubw xmm4, xmm5
psubw xmm4, xmm6
; b = y + hiword(9324 * (u << 4))
movdqa xmm6, [c9324]
pmulhw xmm6, xmm2
movdqa xmm5, xmm0
paddw xmm5, xmm6
packuswb xmm3, xmm3 ; b
packuswb xmm4, xmm4 ; g
punpcklbw xmm3, xmm4 ; gb
pxor xmm4, xmm4 ; a
packuswb xmm5, xmm5 ; r
punpcklbw xmm5, xmm4 ; ar
movdqa xmm4, xmm3
punpcklwd xmm3, xmm5 ; argb
movdqa [edi], xmm3
lea edi, [edi + 16]
punpckhwd xmm4, xmm5 ; argb
movdqa [edi], xmm4
lea edi, [edi + 16]
ret;
;int
;i420_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC i420_to_rgb32_x86_sse2
push ebx
push esi
push edi
push ebp
mov edi, [esp + 32] ; rgbs
mov ecx, [esp + 24] ; width
mov edx, ecx
mov ebp, [esp + 28] ; height
mov eax, ebp
shr ebp, 1
imul eax, ecx ; eax = width * height
mov esi, [esp + 20] ; y
mov ebx, esi ; u = y + width * height
add ebx, eax
; local vars
; char* yptr1
; char* yptr2
; char* uptr
; char* vptr
; int* rgbs1
; int* rgbs2
; int width
sub esp, 28 ; local vars, 28 bytes
mov [esp + 0], esi ; save y1
add esi, edx
mov [esp + 4], esi ; save y2
mov [esp + 8], ebx ; save u
shr eax, 2
add ebx, eax ; v = u + (width * height / 4)
mov [esp + 12], ebx ; save v
mov [esp + 16], edi ; save rgbs1
mov eax, edx
shl eax, 2
add edi, eax
mov [esp + 20], edi ; save rgbs2
loop_y:
mov ecx, edx ; width
shr ecx, 3
; save edx
mov [esp + 24], edx
;prefetchnta 4096[esp + 0] ; y
;prefetchnta 1024[esp + 8] ; u
;prefetchnta 1024[esp + 12] ; v
loop_x:
mov esi, [esp + 0] ; y1
mov ebx, [esp + 8] ; u
mov edx, [esp + 12] ; v
mov edi, [esp + 16] ; rgbs1
; y1
call do8_uv
mov [esp + 0], esi ; y1
mov [esp + 16], edi ; rgbs1
mov esi, [esp + 4] ; y2
mov edi, [esp + 20] ; rgbs2
; y2
call do8
mov [esp + 4], esi ; y2
mov [esp + 8], ebx ; u
mov [esp + 12], edx ; v
mov [esp + 20], edi ; rgbs2
dec ecx ; width
jnz loop_x
; restore edx
mov edx, [esp + 24]
; update y1 and 2
mov eax, [esp + 0]
mov ebx, edx
add eax, ebx
mov [esp + 0], eax
mov eax, [esp + 4]
add eax, ebx
mov [esp + 4], eax
; update rgb1 and 2
mov eax, [esp + 16]
mov ebx, edx
shl ebx, 2
add eax, ebx
mov [esp + 16], eax
mov eax, [esp + 20]
add eax, ebx
mov [esp + 20], eax
mov ecx, ebp
dec ecx ; height
mov ebp, ecx
jnz loop_y
add esp, 28
mov eax, 0
pop ebp
pop edi
pop esi
pop ebx
ret
align 16

@ -0,0 +1,22 @@
%macro PROC 1
align 16
global %1
%1:
%endmacro
;int
;uyvy_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC uyvy_to_rgb32_x86_sse2
push ebx
push esi
push edi
mov eax, 0
pop edi
pop esi
pop ebx
ret
align 16

@ -0,0 +1,22 @@
%macro PROC 1
align 16
global %1
%1:
%endmacro
;int
;yuy2_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC yuy2_to_rgb32_x86_sse2
push ebx
push esi
push edi
mov eax, 0
pop edi
pop esi
pop ebx
ret
align 16

@ -0,0 +1,243 @@
;
;Copyright 2014 Jay Sorg
;
;Permission to use, copy, modify, distribute, and sell this software and its
;documentation for any purpose is hereby granted without fee, provided that
;the above copyright notice appear in all copies and that both that
;copyright notice and this permission notice appear in supporting
;documentation.
;
;The above copyright notice and this permission notice shall be included in
;all copies or substantial portions of the Software.
;
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
;AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
;CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;
;YV12 to RGB32
;x86 SSE2 32 bit
;
; RGB to YUV
; 0.299 0.587 0.114
; -0.14713 -0.28886 0.436
; 0.615 -0.51499 -0.10001
; YUV to RGB
; 1 0 1.13983
; 1 -0.39465 -0.58060
; 1 2.03211 0
; shift left 12
; 4096 0 4669
; 4096 -1616 -2378
; 4096 9324 0
SECTION .data
align 16
c128 times 8 dw 128
c4669 times 8 dw 4669
c1616 times 8 dw 1616
c2378 times 8 dw 2378
c9324 times 8 dw 9324
SECTION .text
%macro PROC 1
align 16
global %1
%1:
%endmacro
do8_uv:
; u
movd xmm1, [ebx] ; 4 at a time
lea ebx, [ebx + 4]
punpcklbw xmm1, xmm1
pxor xmm6, xmm6
punpcklbw xmm1, xmm6
movdqa xmm7, [c128]
psubw xmm1, xmm7
psllw xmm1, 4
; v
movd xmm2, [edx] ; 4 at a time
lea edx, [edx + 4]
punpcklbw xmm2, xmm2
punpcklbw xmm2, xmm6
psubw xmm2, xmm7
psllw xmm2, 4
do8:
; y
movq xmm0, [esi] ; 8 at a time
lea esi, [esi + 8]
pxor xmm6, xmm6
punpcklbw xmm0, xmm6
; r = y + hiword(4669 * (v << 4))
movdqa xmm4, [c4669]
pmulhw xmm4, xmm2
movdqa xmm3, xmm0
paddw xmm3, xmm4
; g = y - hiword(1616 * (u << 4)) - hiword(2378 * (v << 4))
movdqa xmm5, [c1616]
pmulhw xmm5, xmm1
movdqa xmm6, [c2378]
pmulhw xmm6, xmm2
movdqa xmm4, xmm0
psubw xmm4, xmm5
psubw xmm4, xmm6
; b = y + hiword(9324 * (u << 4))
movdqa xmm6, [c9324]
pmulhw xmm6, xmm1
movdqa xmm5, xmm0
paddw xmm5, xmm6
packuswb xmm3, xmm3 ; b
packuswb xmm4, xmm4 ; g
punpcklbw xmm3, xmm4 ; gb
pxor xmm4, xmm4 ; a
packuswb xmm5, xmm5 ; r
punpcklbw xmm5, xmm4 ; ar
movdqa xmm4, xmm3
punpcklwd xmm3, xmm5 ; argb
movdqa [edi], xmm3
lea edi, [edi + 16]
punpckhwd xmm4, xmm5 ; argb
movdqa [edi], xmm4
lea edi, [edi + 16]
ret;
;int
;yv12_to_rgb32_x86_sse2(unsigned char *yuvs, int width, int height, int *rgbs)
PROC yv12_to_rgb32_x86_sse2
push ebx
push esi
push edi
push ebp
mov edi, [esp + 32] ; rgbs
mov ecx, [esp + 24] ; width
mov edx, ecx
mov ebp, [esp + 28] ; height
mov eax, ebp
shr ebp, 1
imul eax, ecx ; eax = width * height
mov esi, [esp + 20] ; y
mov ebx, esi ; u = y + width * height
add ebx, eax
; local vars
; char* yptr1
; char* yptr2
; char* uptr
; char* vptr
; int* rgbs1
; int* rgbs2
; int width
sub esp, 28 ; local vars, 28 bytes
mov [esp + 0], esi ; save y1
add esi, edx
mov [esp + 4], esi ; save y2
mov [esp + 8], ebx ; save u
shr eax, 2
add ebx, eax ; v = u + (width * height / 4)
mov [esp + 12], ebx ; save v
mov [esp + 16], edi ; save rgbs1
mov eax, edx
shl eax, 2
add edi, eax
mov [esp + 20], edi ; save rgbs2
loop_y:
mov ecx, edx ; width
shr ecx, 3
; save edx
mov [esp + 24], edx
;prefetchnta 4096[esp + 0] ; y
;prefetchnta 1024[esp + 8] ; u
;prefetchnta 1024[esp + 12] ; v
loop_x:
mov esi, [esp + 0] ; y1
mov ebx, [esp + 8] ; u
mov edx, [esp + 12] ; v
mov edi, [esp + 16] ; rgbs1
; y1
call do8_uv
mov [esp + 0], esi ; y1
mov [esp + 16], edi ; rgbs1
mov esi, [esp + 4] ; y2
mov edi, [esp + 20] ; rgbs2
; y2
call do8
mov [esp + 4], esi ; y2
mov [esp + 8], ebx ; u
mov [esp + 12], edx ; v
mov [esp + 20], edi ; rgbs2
dec ecx ; width
jnz loop_x
; restore edx
mov edx, [esp + 24]
; update y1 and 2
mov eax, [esp + 0]
mov ebx, edx
add eax, ebx
mov [esp + 0], eax
mov eax, [esp + 4]
add eax, ebx
mov [esp + 4], eax
; update rgb1 and 2
mov eax, [esp + 16]
mov ebx, edx
shl ebx, 2
add eax, ebx
mov [esp + 16], eax
mov eax, [esp + 20]
add eax, ebx
mov [esp + 20], eax
mov ecx, ebp
dec ecx ; height
mov ebp, ecx
jnz loop_y
add esp, 28
mov eax, 0
pop ebp
pop edi
pop esi
pop ebx
ret
align 16

@ -39,6 +39,8 @@ This is the main driver file
#include <mi.h>
#include <randrstr.h>
#include <xf86Modes.h>
#include "rdp.h"
#include "rdpPri.h"
#include "rdpDraw.h"
@ -51,14 +53,8 @@ This is the main driver file
#include "rdpGlyphs.h"
#include "rdpPixmap.h"
#include "rdpClientCon.h"
#define XRDP_DRIVER_NAME "XRDPDEV"
#define XRDP_NAME "XRDPDEV"
#define XRDP_VERSION 1000
#define PACKAGE_VERSION_MAJOR 1
#define PACKAGE_VERSION_MINOR 0
#define PACKAGE_VERSION_PATCHLEVEL 0
#include "rdpXv.h"
#include "rdpSimd.h"
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -449,13 +445,20 @@ rdpScreenInit(ScreenPtr pScreen, int argc, char **argv)
LLOGLN(0, ("rdpScreenInit: fbScreenInit failed"));
return FALSE;
}
#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 14, 0, 0, 0)
/* 1.13 has this function, 1.14 and up does not */
miInitializeBackingStore(pScreen);
#endif
/* try in init simd functions */
rdpSimdInit(pScreen, pScrn);
#if 0
#if defined(XvExtension) && XvExtension
/* XVideo */
if (rdp_xv_init(pScreen, pScrn) != 0)
if (!rdpXvInit(pScreen, pScrn))
{
LLOGLN(0, ("rdpScreenInit: rdp_xv_init failed"));
LLOGLN(0, ("rdpScreenInit: rdpXvInit failed"));
}
#endif
@ -658,7 +661,7 @@ rdpProbe(DriverPtr drv, int flags)
found_screen = 1;
pscrn->driverVersion = XRDP_VERSION;
pscrn->driverName = XRDP_DRIVER_NAME;
pscrn->name = XRDP_NAME;
pscrn->name = XRDP_DRIVER_NAME;
pscrn->Probe = rdpProbe;
pscrn->PreInit = rdpPreInit;
pscrn->ScreenInit = rdpScreenInit;
@ -710,7 +713,7 @@ static void
rdpIdentify(int flags)
{
LLOGLN(0, ("rdpIdentify:"));
xf86PrintChipsets(XRDP_NAME, "driver for xrdp", g_Chipsets);
xf86PrintChipsets(XRDP_DRIVER_NAME, "driver for xrdp", g_Chipsets);
}
/*****************************************************************************/

@ -52,14 +52,6 @@ xrdp keyboard module
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define XRDP_DRIVER_NAME "XRDPKEYB"
#define XRDP_NAME "XRDPKEYB"
#define XRDP_VERSION 1000
#define PACKAGE_VERSION_MAJOR 1
#define PACKAGE_VERSION_MINOR 0
#define PACKAGE_VERSION_PATCHLEVEL 0
#define MIN_KEY_CODE 8
#define MAX_KEY_CODE 255
#define NO_OF_KEYS ((MAX_KEY_CODE - MIN_KEY_CODE) + 1)
@ -688,7 +680,7 @@ rdpkeybUnInit(InputDriverPtr drv, InputInfoPtr info, int flags)
static InputDriverRec rdpkeyb =
{
PACKAGE_VERSION_MAJOR, /* version */
XRDP_NAME, /* name */
XRDP_KEYB_NAME, /* name */
NULL, /* identify */
rdpkeybPreInit, /* preinit */
rdpkeybUnInit, /* uninit */
@ -715,7 +707,7 @@ rdpkeybUnplug(pointer p)
/******************************************************************************/
static XF86ModuleVersionInfo rdpkeybVersionRec =
{
XRDP_DRIVER_NAME,
XRDP_KEYB_NAME,
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,

@ -50,14 +50,6 @@ xrdp mouse module
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
#define XRDP_DRIVER_NAME "XRDPMOUSE"
#define XRDP_NAME "XRDPMOUSE"
#define XRDP_VERSION 1000
#define PACKAGE_VERSION_MAJOR 1
#define PACKAGE_VERSION_MINOR 0
#define PACKAGE_VERSION_PATCHLEVEL 0
/******************************************************************************/
static void
rdpmouseDeviceInit(void)
@ -323,7 +315,7 @@ rdpmouseUnInit(InputDriverPtr drv, InputInfoPtr info, int flags)
static InputDriverRec rdpmouse =
{
PACKAGE_VERSION_MAJOR, /* version */
XRDP_NAME, /* name */
XRDP_MOUSE_NAME, /* name */
NULL, /* identify */
rdpmousePreInit, /* preinit */
rdpmouseUnInit, /* uninit */
@ -350,7 +342,7 @@ rdpmouseUnplug(pointer p)
/******************************************************************************/
static XF86ModuleVersionInfo rdpmouseVersionRec =
{
XRDP_DRIVER_NAME,
XRDP_MOUSE_NAME,
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,

@ -15,6 +15,12 @@ EXTRA_INCLUDES += -I$(prefix)/include
EXTRA_FLAGS += -L$(prefix)/lib -Wl,-rpath -Wl,$(prefix)/lib
endif
if XRDP_RFXCODEC
EXTRA_DEFINES += -DXRDP_RFXCODEC
EXTRA_INCLUDES += -I$(top_srcdir)/librfxcodec/include
EXTRA_LIBS += $(top_srcdir)/librfxcodec/src/librfxencode.a
endif
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
@ -45,11 +51,13 @@ xrdp_SOURCES = \
xrdp_painter.c \
xrdp_process.c \
xrdp_region.c \
xrdp_wm.c
xrdp_wm.c \
xrdp_encoder.c
xrdp_LDADD = \
$(top_builddir)/common/libcommon.la \
$(top_builddir)/libxrdp/libxrdp.la
$(top_builddir)/libxrdp/libxrdp.la \
$(EXTRA_LIBS)
xrdp_LDFLAGS = \
$(EXTRA_FLAGS)
@ -57,7 +65,8 @@ xrdp_LDFLAGS = \
xrdpsysconfdir=$(sysconfdir)/xrdp
xrdpsysconf_DATA = \
xrdp.ini
xrdp.ini \
xrdp_keyboard.ini
xrdppkgdatadir=$(datadir)/xrdp
@ -70,4 +79,3 @@ xrdppkgdata_DATA = \
sans-10.fv1 \
cursor0.cur \
cursor1.cur

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -231,7 +231,7 @@ get_keymaps(int keylayout, struct xrdp_keymap *keymap)
{
fd = g_file_open(filename);
if (fd > 0)
if (fd != -1)
{
lkeymap = (struct xrdp_keymap *)g_malloc(sizeof(struct xrdp_keymap), 0);
/* make a copy of the build in kaymap */

@ -64,6 +64,7 @@ m 0x32 50 0000 8000
, 0x33 51 0000 8000
. 0x34 52 0000 8000
/ 0x35 53 0000 8000
/(keypad) 0x35 53 0100 8100
right shift 0x36 54 0000/4000 c000
*(keypad) 0x37 55 0000 8000
print scrn 0x37 55 0100 8100
@ -87,7 +88,7 @@ scroll lock 0x46 70 0000/4000 c000
home 0x47 71 0100 8100
8(keypad) 0x48 72 0000 8000
up arrow 0x48 72 0100 8100
9(kaypad) 0x49 73 0000 8000
9(keypad) 0x49 73 0000 8000
pg up 0x49 73 0100 8100
-(keypad) 0x4a 74 0000 8000
4(keypad) 0x4b 75 0000 8000
@ -102,7 +103,7 @@ end 0x4f 79 0100 8100
down arrow 0x50 80 0100 8100
3(keypad) 0x51 81 0000 8000
pg down 0x51 81 0100 8100
o(keypad) 0x52 82 0000 8000
0(keypad) 0x52 82 0000 8000
insert 0x52 82 0100 8100
.(keypad) 0x53 83 0000 8000
delete 0x53 83 0100 8100

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,10 @@
#include "xrdp.h"
#include "log.h"
#if !defined(PACKAGE_VERSION)
#define PACKAGE_VERSION "???"
#endif
#define THREAD_WAITING 100
static struct xrdp_listen *g_listen = 0;
@ -435,8 +439,8 @@ main(int argc, char **argv)
{
g_writeln("");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2013");
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("Copyright (C) Jay Sorg 2004-2014");
g_writeln("See http://www.xrdp.org for more information.");
g_writeln("");
g_writeln("Usage: xrdp [options]");
g_writeln(" --help: show help");
@ -453,8 +457,8 @@ main(int argc, char **argv)
{
g_writeln("");
g_writeln("xrdp: A Remote Desktop Protocol server.");
g_writeln("Copyright (C) Jay Sorg 2004-2013");
g_writeln("See http://xrdp.sourceforge.net for more information.");
g_writeln("Copyright (C) Jay Sorg 2004-2014");
g_writeln("See http://www.xrdp.org for more information.");
g_writeln("Version %s", PACKAGE_VERSION);
g_writeln("");
g_deinit();
@ -538,9 +542,19 @@ main(int argc, char **argv)
g_file_close(0);
g_file_close(1);
g_file_close(2);
g_file_open("/dev/null");
g_file_open("/dev/null");
g_file_open("/dev/null");
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
if (g_file_open("/dev/null") < 0)
{
}
/* end of daemonizing code */
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@
#include "parse.h"
#include "trans.h"
#include "list.h"
#include "list16.h"
#include "libxrdpinc.h"
#include "xrdp_constants.h"
#include "xrdp_types.h"
@ -137,6 +138,8 @@ callback(long id, int msg, long param1, long param2, long param3, long param4);
int APP_CC
xrdp_wm_delete_all_childs(struct xrdp_wm* self);
int APP_CC
xrdp_wm_show_log(struct xrdp_wm *self);
int APP_CC
xrdp_wm_log_msg(struct xrdp_wm* self, char* msg);
int APP_CC
xrdp_wm_get_wait_objs(struct xrdp_wm* self, tbus* robjs, int* rc,
@ -206,6 +209,8 @@ xrdp_bitmap_copy_box(struct xrdp_bitmap* self,
struct xrdp_bitmap* dest,
int x, int y, int cx, int cy);
int APP_CC
xrdp_bitmap_hash_crc(struct xrdp_bitmap *self);
int APP_CC
xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self,
struct xrdp_bitmap* dest,
int x, int y, int cx, int cy);
@ -213,9 +218,6 @@ int APP_CC
xrdp_bitmap_compare(struct xrdp_bitmap* self,
struct xrdp_bitmap* b);
int APP_CC
xrdp_bitmap_compare_with_crc(struct xrdp_bitmap* self,
struct xrdp_bitmap* b);
int APP_CC
xrdp_bitmap_invalidate(struct xrdp_bitmap* self, struct xrdp_rect* rect);
int APP_CC
xrdp_bitmap_def_proc(struct xrdp_bitmap* self, int msg,
@ -404,7 +406,8 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int DEFAULT_CC
server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
char *data, int width, int height,
int flags, int frame_id);
int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask);

@ -1,4 +1,3 @@
[globals]
# xrdp.ini file version number
ini_version=1
@ -6,10 +5,19 @@ ini_version=1
bitmap_cache=yes
bitmap_compression=yes
port=3389
crypt_level=high
allow_channels=true
max_bpp=24
max_bpp=32
fork=yes
# minimum security level allowed for client
# can be 'none', 'low', 'medium', 'high', 'fips'
crypt_level=high
# security layer can be 'tls', 'rdp' or 'negotiate'
# for client compatible layer
security_layer=rdp
# X.509 certificate and private key
# openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
certificate=
key_file=
# regulate if the listening socket use socket option tcp_nodelay
# no buffering will be performed in the TCP stack
@ -42,18 +50,22 @@ grey=dedede
# when true, userid/password *must* be passed on cmd line
# require_credentials=yes
#bulk_compression=yes
bulk_compression=yes
# You can set the PAM error text in a gateway setup (MAX 256 chars)
#pamerrortxt=change your password according to policy at http://url
#new_cursors=no
#nego_sec_layer=0
new_cursors=yes
allow_multimon=true
# fastpath - can be set to input / output / both / none
use_fastpath=both
#
# configure login screen
#
# Login Screen Window Title
#ls_title=My Login Title
# top level window background color in RGB format
ls_top_window_bg_color=009cb5
@ -64,7 +76,11 @@ ls_height=430
# login screen background color in RGB format
ls_bg_color=dedede
# optional background image filename (bmp format).
#ls_background_image=
# logo
# full path to bmp-file or file in shared folder
ls_logo_filename=
ls_logo_x_pos=55
ls_logo_y_pos=50
@ -112,6 +128,7 @@ drdynvc=true
cliprdr=true
rail=true
xrdpvr=true
tcutils=true
# for debugging xrdp, in section xrdp1, change port=-1 to this:
# port=/tmp/.xrdp/xrdp_display_10
@ -178,6 +195,16 @@ port=ask3389
username=ask
password=ask
[Session manager]
name=Session manager
lib=libxup.so
username=ask
password=ask
ip=127.0.0.1
port=-1
xserverbpp=24
code=20
# You can override the common channel settings for each session type
#channel.rdpdr=true
#channel.rdpsnd=true

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,9 +23,22 @@
#include "xrdp.h"
#include "log.h"
static int g_crc_seed = 0xffffffff;
static int g_crc_table[256] =
#include "crc16.h"
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
do \
{ \
if (_level < LLOG_LEVEL) \
{ \
g_write("xrdp:xrdp_bitmap [%10.10u]: ", g_time3()); \
g_writeln _args ; \
} \
} \
while (0)
static const int g_crc_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@ -72,10 +85,10 @@ static int g_crc_table[256] =
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define CRC_START(in_crc) (in_crc) = g_crc_seed
#define CRC_START(in_crc) (in_crc) = 0xFFFFFFFF
#define CRC_PASS(in_pixel, in_crc) \
(in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8)
#define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed)
#define CRC_END(in_crc) (in_crc) = ((in_crc) ^ 0xFFFFFFFF)
/*****************************************************************************/
struct xrdp_bitmap *APP_CC
@ -136,15 +149,44 @@ xrdp_bitmap_create_with_data(int width, int height,
struct xrdp_wm *wm)
{
struct xrdp_bitmap *self = (struct xrdp_bitmap *)NULL;
#if defined(NEED_ALIGN)
tintptr data_as_int;
int Bpp;
#endif
self = (struct xrdp_bitmap *)g_malloc(sizeof(struct xrdp_bitmap), 1);
self->type = WND_TYPE_BITMAP;
self->width = width;
self->height = height;
self->bpp = bpp;
self->wm = wm;
#if defined(NEED_ALIGN)
data_as_int = (tintptr) data;
if (((bpp >= 24) && (data_as_int & 3)) ||
(((bpp == 15) || (bpp == 16)) && (data_as_int & 1)))
{
/* got to copy data here, it's not alligned
other calls in this file assume alignment */
Bpp = 4;
switch (bpp)
{
case 8:
Bpp = 1;
break;
case 15:
Bpp = 2;
break;
case 16:
Bpp = 2;
break;
}
self->data = (char *)g_malloc(width * height * Bpp, 0);
g_memcpy(self->data, data, width * height * Bpp);
return self;
}
#endif
self->data = data;
self->do_not_free_data = 1;
self->wm = wm;
return self;
}
@ -400,7 +442,6 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
return 1;
}
s = (struct stream *)NULL;
fd = g_file_open(filename);
if (fd != -1)
@ -428,7 +469,14 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
g_file_read(fd, s->data, 4);
in_uint32_le(s, size);
/* read bmp header */
g_file_seek(fd, 14);
if (g_file_seek(fd, 14) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
free_stream(s);
g_file_close(fd);
return 1;
}
init_stream(s, 8192);
g_file_read(fd, s->data, 40); /* size better be 40 */
in_uint32_le(s, header.size);
@ -455,7 +503,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
if (header.bit_count == 24) /* 24 bit bitmap */
{
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
xrdp_bitmap_resize(self, header.image_width, header.image_height);
size = header.image_width * header.image_height * 3;
init_stream(s, size);
@ -508,7 +560,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
else if (header.bit_count == 8) /* 8 bit bitmap */
{
/* read palette */
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
init_stream(s, 8192);
g_file_read(fd, s->data, header.clr_used * sizeof(int));
@ -565,7 +621,11 @@ xrdp_bitmap_load(struct xrdp_bitmap *self, const char *filename, int *palette)
else if (header.bit_count == 4) /* 4 bit bitmap */
{
/* read palette */
g_file_seek(fd, 14 + header.size);
if (g_file_seek(fd, 14 + header.size) < 0)
{
log_message(LOG_LEVEL_ERROR, "xrdp_bitmap_load: seek error in file %s\n",
filename);
}
init_stream(s, 8192);
g_file_read(fd, s->data, header.clr_used * sizeof(int));
@ -666,7 +726,7 @@ xrdp_bitmap_get_pixel(struct xrdp_bitmap *self, int x, int y)
{
return GETPIXEL16(self->data, x, y, self->width);
}
else if (self->bpp == 24)
else if (self->bpp >= 24)
{
return GETPIXEL32(self->data, x, y, self->width);
}
@ -699,7 +759,7 @@ xrdp_bitmap_set_pixel(struct xrdp_bitmap *self, int x, int y, int pixel)
{
SETPIXEL16(self->data, x, y, self->width, pixel);
}
else if (self->bpp == 24)
else if (self->bpp >= 24)
{
SETPIXEL32(self->data, x, y, self->width, pixel);
}
@ -716,11 +776,17 @@ xrdp_bitmap_copy_box(struct xrdp_bitmap *self,
struct xrdp_bitmap *dest,
int x, int y, int cx, int cy)
{
int i = 0;
int j = 0;
int destx = 0;
int desty = 0;
int pixel = 0;
int i;
int destx;
int desty;
int incs;
int incd;
tui8 *s8;
tui8 *d8;
tui16 *s16;
tui16 *d16;
tui32 *s32;
tui32 *d32;
if (self == 0)
{
@ -760,37 +826,56 @@ xrdp_bitmap_copy_box(struct xrdp_bitmap *self,
return 1;
}
if (self->bpp == 24)
if (self->bpp >= 24)
{
s32 = ((tui32 *)(self->data)) + (self->width * y + x);
d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
pixel = GETPIXEL32(self->data, j + x, i + y, self->width);
SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel);
}
g_memcpy(d32, s32, cx * 4);
s32 += cx;
d32 += cx;
s32 += incs;
d32 += incd;
}
}
else if (self->bpp == 15 || self->bpp == 16)
{
s16 = ((tui16 *)(self->data)) + (self->width * y + x);
d16 = ((tui16 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
pixel = GETPIXEL16(self->data, j + x, i + y, self->width);
SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel);
}
g_memcpy(d16, s16, cx * 2);
s16 += cx;
d16 += cx;
s16 += incs;
d16 += incd;
}
}
else if (self->bpp == 8)
{
s8 = ((tui8 *)(self->data)) + (self->width * y + x);
d8 = ((tui8 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
pixel = GETPIXEL8(self->data, j + x, i + y, self->width);
SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel);
}
g_memcpy(d8, s8, cx);
s8 += cx;
d8 += cx;
s8 += incs;
d8 += incd;
}
}
else
@ -801,6 +886,51 @@ xrdp_bitmap_copy_box(struct xrdp_bitmap *self,
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_bitmap_hash_crc(struct xrdp_bitmap *self)
{
void *hash;
int bytes;
int crc;
int index;
char hash_data[16];
if (self->bpp >= 24)
{
bytes = self->width * self->height * 4;
}
else if (self->bpp == 15 || self->bpp == 16)
{
bytes = self->width * self->height * 2;
}
else if (self->bpp == 8)
{
bytes = self->width * self->height;
}
else
{
return 1;
}
hash = ssl_md5_info_create();
ssl_md5_transform(hash, self->data, bytes);
ssl_md5_complete(hash, hash_data);
ssl_md5_info_delete(hash);
CRC_START(crc);
CRC_PASS(self->width, crc);
CRC_PASS(self->width >> 8, crc);
CRC_PASS(self->height, crc);
CRC_PASS(self->height >> 8, crc);
for (index = 0; index < 16; index++)
{
CRC_PASS(hash_data[index], crc);
}
CRC_END(crc);
self->crc32 = crc;
self->crc16 = self->crc32 & 0xffff;
return 0;
}
/*****************************************************************************/
/* copy part of self at x, y to 0, 0 in dest */
/* returns error */
@ -809,20 +939,20 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
struct xrdp_bitmap *dest,
int x, int y, int cx, int cy)
{
int i = 0;
int j = 0;
int destx = 0;
int desty = 0;
int pixel = 0;
int crc = 0;
int incs = 0;
int incd = 0;
unsigned char *s8 = (unsigned char *)NULL;
unsigned char *d8 = (unsigned char *)NULL;
unsigned short *s16 = (unsigned short *)NULL;
unsigned short *d16 = (unsigned short *)NULL;
unsigned int *s32;
unsigned int *d32;
int i;
int j;
int destx;
int desty;
int pixel;
int crc;
int incs;
int incd;
tui8 *s8;
tui8 *d8;
tui16 *s16;
tui16 *d16;
tui32 *s32;
tui32 *d32;
if (self == 0)
{
@ -864,47 +994,123 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
CRC_START(crc);
if (self->bpp == 24)
CRC_PASS(self->width, crc);
CRC_PASS(self->width >> 8, crc);
CRC_PASS(self->height, crc);
CRC_PASS(self->height >> 8, crc);
if (self->bpp == 32)
{
s32 = ((unsigned int *)(self->data)) + (self->width * y + x);
d32 = ((unsigned int *)(dest->data)) + (dest->width * desty + destx);
s32 = ((tui32 *)(self->data)) + (self->width * y + x);
d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
for (i = 0; i < cy; i++)
{
j = 0;
while (j < cx - 4)
{
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
CRC_PASS(pixel >> 24, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
CRC_PASS(pixel >> 24, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
CRC_PASS(pixel >> 24, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
CRC_PASS(pixel >> 24, crc);
s32++;
d32++;
j += 4;
}
while (j < cx)
{
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
CRC_PASS(pixel >> 24, crc);
s32++;
d32++;
j += 1;
}
s32 += incs;
d32 += incd;
}
}
else if (self->bpp == 24)
{
s32 = ((tui32 *)(self->data)) + (self->width * y + x);
d32 = ((tui32 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
for (i = 0; i < cy; i++)
{
j = 0;
while (j < cx - 4)
{
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
s32++;
d32++;
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
s32++;
d32++;
@ -913,10 +1119,10 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
while (j < cx)
{
pixel = *s32;
*d32 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
CRC_PASS(pixel >> 16, crc);
*d32 = pixel;
s32++;
d32++;
@ -929,8 +1135,8 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
}
else if (self->bpp == 15 || self->bpp == 16)
{
s16 = ((unsigned short *)(self->data)) + (self->width * y + x);
d16 = ((unsigned short *)(dest->data)) + (dest->width * desty + destx);
s16 = ((tui16 *)(self->data)) + (self->width * y + x);
d16 = ((tui16 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
@ -939,9 +1145,9 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
for (j = 0; j < cx; j++)
{
pixel = *s16;
*d16 = pixel;
CRC_PASS(pixel, crc);
CRC_PASS(pixel >> 8, crc);
*d16 = pixel;
s16++;
d16++;
}
@ -952,8 +1158,8 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
}
else if (self->bpp == 8)
{
s8 = ((unsigned char *)(self->data)) + (self->width * y + x);
d8 = ((unsigned char *)(dest->data)) + (dest->width * desty + destx);
s8 = ((tui8 *)(self->data)) + (self->width * y + x);
d8 = ((tui8 *)(dest->data)) + (dest->width * desty + destx);
incs = self->width - cx;
incd = dest->width - cx;
@ -962,8 +1168,8 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
for (j = 0; j < cx; j++)
{
pixel = *s8;
CRC_PASS(pixel, crc);
*d8 = pixel;
CRC_PASS(pixel, crc);
s8++;
d8++;
}
@ -978,7 +1184,14 @@ xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap *self,
}
CRC_END(crc);
dest->crc = crc;
dest->crc32 = crc;
dest->crc16 = dest->crc32 & 0xffff;
LLOGLN(10, ("xrdp_bitmap_copy_box_with_crc: crc16 0x%4.4x",
dest->crc16));
LLOGLN(10, ("xrdp_bitmap_copy_box_with_crc: width %d height %d",
dest->width, dest->height));
return 0;
}
@ -988,45 +1201,8 @@ int APP_CC
xrdp_bitmap_compare(struct xrdp_bitmap *self,
struct xrdp_bitmap *b)
{
if (self == 0)
{
return 0;
}
if (b == 0)
{
return 0;
}
if (self->bpp != b->bpp)
{
return 0;
}
if (self->width != b->width)
{
return 0;
}
if (self->height != b->height)
{
return 0;
}
LLOGLN(10, ("xrdp_bitmap_compare:"));
if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0)
{
return 1;
}
return 0;
}
/*****************************************************************************/
/* returns true if they are the same, else returns false */
int APP_CC
xrdp_bitmap_compare_with_crc(struct xrdp_bitmap *self,
struct xrdp_bitmap *b)
{
if (self == 0)
{
return 0;
@ -1052,7 +1228,7 @@ xrdp_bitmap_compare_with_crc(struct xrdp_bitmap *self,
return 0;
}
if (self->crc == b->crc)
if (g_memcmp(self->data, b->data, b->height * b->line_size) == 0)
{
return 1;
}
@ -1617,42 +1793,6 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
if (self->child_list != 0)
{
i = list_index_of(self->child_list, (long)self->focused_control);
}
if (shift)
{
i--;
if (i < 0)
{
i = self->child_list->count - 1;
}
}
else
{
i++;
if (i >= self->child_list->count)
{
i = 0;
}
}
n = self->child_list->count;
b = (struct xrdp_bitmap *)list_get_item(self->child_list, i);
while (b != self->focused_control && b != 0 && n > 0)
{
n--;
if (b->tab_stop)
{
focus_out_control = self->focused_control;
self->focused_control = b;
xrdp_bitmap_invalidate(focus_out_control, 0);
xrdp_bitmap_invalidate(b, 0);
break;
}
if (shift)
{
@ -1673,7 +1813,43 @@ xrdp_bitmap_def_proc(struct xrdp_bitmap *self, int msg,
}
}
n = self->child_list->count;
b = (struct xrdp_bitmap *)list_get_item(self->child_list, i);
while (b != self->focused_control && b != 0 && n > 0)
{
n--;
if (b->tab_stop)
{
focus_out_control = self->focused_control;
self->focused_control = b;
xrdp_bitmap_invalidate(focus_out_control, 0);
xrdp_bitmap_invalidate(b, 0);
break;
}
if (shift)
{
i--;
if (i < 0)
{
i = self->child_list->count - 1;
}
}
else
{
i++;
if (i >= self->child_list->count)
{
i = 0;
}
}
b = (struct xrdp_bitmap *)list_get_item(self->child_list, i);
}
}
}
else if (scan_code == 28) /* enter */

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@
#include "xrdp.h"
#include "log.h"
#include "crc16.h"
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
@ -33,6 +34,59 @@
} \
while (0)
/*****************************************************************************/
static int APP_CC
xrdp_cache_reset_lru(struct xrdp_cache *self)
{
int index;
int jndex;
struct xrdp_lru_item *lru;
for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++)
{
/* fist item */
lru = &(self->bitmap_lrus[index][0]);
lru->next = 1;
lru->prev = -1;
/* middle items */
for (jndex = 1; jndex < XRDP_MAX_BITMAP_CACHE_IDX - 1; jndex++)
{
lru = &(self->bitmap_lrus[index][jndex]);
lru->next = jndex + 1;
lru->prev = jndex - 1;
}
/* last item */
lru = &(self->bitmap_lrus[index][XRDP_MAX_BITMAP_CACHE_IDX - 1]);
lru->next = -1;
lru->prev = XRDP_MAX_BITMAP_CACHE_IDX - 2;
self->lru_head[index] = 0;
self->lru_tail[index] = XRDP_MAX_BITMAP_CACHE_IDX - 1;
self->lru_reset[index] = 1;
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_cache_reset_crc(struct xrdp_cache *self)
{
int index;
int jndex;
for (index = 0; index < XRDP_MAX_BITMAP_CACHE_ID; index++)
{
for (jndex = 0; jndex < 64 * 1024; jndex++)
{
/* it's ok to deinit a zero'ed out struct list16 */
list16_deinit(&(self->crc16[index][jndex]));
list16_init(&(self->crc16[index][jndex]));
}
}
return 0;
}
/*****************************************************************************/
struct xrdp_cache *APP_CC
xrdp_cache_create(struct xrdp_wm *owner,
@ -65,6 +119,8 @@ xrdp_cache_create(struct xrdp_wm *owner,
self->bitmap_cache_version = client_info->bitmap_cache_version;
self->pointer_cache_entries = client_info->pointer_cache_entries;
self->xrdp_os_del_list = list_create();
xrdp_cache_reset_lru(self);
xrdp_cache_reset_crc(self);
LLOGLN(10, ("xrdp_cache_create: 0 %d 1 %d 2 %d",
self->cache1_entries, self->cache2_entries, self->cache3_entries));
return self;
@ -108,6 +164,15 @@ xrdp_cache_delete(struct xrdp_cache *self)
list_delete(self->xrdp_os_del_list);
/* free all crc lists */
for (i = 0; i < XRDP_MAX_BITMAP_CACHE_ID; i++)
{
for (j = 0; j < 64 * 1024; j++)
{
list16_deinit(&(self->crc16[i][j]));
}
}
g_free(self);
}
@ -157,157 +222,228 @@ xrdp_cache_reset(struct xrdp_cache *self,
self->bitmap_cache_persist_enable = client_info->bitmap_cache_persist_enable;
self->bitmap_cache_version = client_info->bitmap_cache_version;
self->pointer_cache_entries = client_info->pointer_cache_entries;
xrdp_cache_reset_lru(self);
xrdp_cache_reset_crc(self);
return 0;
}
#define COMPARE_WITH_CRC(_b1, _b2) \
((_b1 != 0) && (_b2 != 0) && (_b1->crc == _b2->crc) && \
#define COMPARE_WITH_CRC32(_b1, _b2) \
((_b1 != 0) && (_b2 != 0) && (_b1->crc32 == _b2->crc32) && \
(_b1->bpp == _b2->bpp) && \
(_b1->width == _b2->width) && (_b1->height == _b2->height))
/*****************************************************************************/
/* returns cache id */
int APP_CC
xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
int hints)
static int APP_CC
xrdp_cache_update_lru(struct xrdp_cache *self, int cache_id, int lru_index)
{
int i = 0;
int j = 0;
int oldest = 0;
int cache_id = 0;
int cache_idx = 0;
int bmp_size = 0;
int e = 0;
int Bpp = 0;
int tail_index;
struct xrdp_lru_item *nextlru;
struct xrdp_lru_item *prevlru;
struct xrdp_lru_item *thislru;
struct xrdp_lru_item *taillru;
LLOGLN(10, ("xrdp_cache_update_lru: lru_index %d", lru_index));
if ((lru_index < 0) || (lru_index >= XRDP_MAX_BITMAP_CACHE_IDX))
{
LLOGLN(0, ("xrdp_cache_update_lru: error"));
return 1;
}
if (self->lru_tail[cache_id] == lru_index)
{
/* nothing to do */
return 0;
}
else if (self->lru_head[cache_id] == lru_index)
{
/* moving head item to tail */
e = bitmap->width % 4;
thislru = &(self->bitmap_lrus[cache_id][lru_index]);
nextlru = &(self->bitmap_lrus[cache_id][thislru->next]);
tail_index = self->lru_tail[cache_id];
taillru = &(self->bitmap_lrus[cache_id][tail_index]);
if (e != 0)
/* unhook old */
nextlru->prev = -1;
/* set head to next */
self->lru_head[cache_id] = thislru->next;
/* move to tail and hook up */
taillru->next = lru_index;
thislru->prev = tail_index;
thislru->next = -1;
/* update tail */
self->lru_tail[cache_id] = lru_index;
}
else
{
e = 4 - e;
/* move middle item */
thislru = &(self->bitmap_lrus[cache_id][lru_index]);
prevlru = &(self->bitmap_lrus[cache_id][thislru->prev]);
nextlru = &(self->bitmap_lrus[cache_id][thislru->next]);
tail_index = self->lru_tail[cache_id];
taillru = &(self->bitmap_lrus[cache_id][tail_index]);
/* unhook old */
prevlru->next = thislru->next;
nextlru->prev = thislru->prev;
/* move to tail and hook up */
taillru->next = lru_index;
thislru->prev = tail_index;
thislru->next = -1;
/* update tail */
self->lru_tail[cache_id] = lru_index;
}
return 0;
}
/*****************************************************************************/
/* returns cache id */
int APP_CC
xrdp_cache_add_bitmap(struct xrdp_cache *self, struct xrdp_bitmap *bitmap,
int hints)
{
int index;
int jndex;
int cache_id;
int cache_idx;
int bmp_size;
int e;
int Bpp;
int crc16;
int iig;
int found;
int cache_entries;
int lru_index;
struct list16 *ll;
struct xrdp_bitmap *lbm;
struct xrdp_lru_item *llru;
LLOGLN(10, ("xrdp_cache_add_bitmap:"));
LLOGLN(10, ("xrdp_cache_add_bitmap: crc16 0x%4.4x",
bitmap->crc16));
e = (4 - (bitmap->width % 4)) & 3;
found = 0;
cache_id = 0;
cache_entries = 0;
/* client Bpp, bmp_size */
Bpp = (bitmap->bpp + 7) / 8;
bmp_size = (bitmap->width + e) * bitmap->height * Bpp;
self->bitmap_stamp++;
/* look for match */
if (bmp_size <= self->cache1_size)
{
i = 0;
for (j = 0; j < self->cache1_entries; j++)
{
#ifdef USE_CRC
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
#else
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
#endif
{
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i);
}
}
cache_id = 0;
cache_entries = self->cache1_entries;
}
else if (bmp_size <= self->cache2_size)
{
i = 1;
for (j = 0; j < self->cache2_entries; j++)
{
#ifdef USE_CRC
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
#else
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
#endif
{
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i);
}
}
cache_id = 1;
cache_entries = self->cache2_entries;
}
else if (bmp_size <= self->cache3_size)
{
i = 2;
for (j = 0; j < self->cache3_entries; j++)
{
#ifdef USE_CRC
if (COMPARE_WITH_CRC(self->bitmap_items[i][j].bitmap, bitmap))
#else
if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap))
#endif
{
self->bitmap_items[i][j].stamp = self->bitmap_stamp;
LLOGLN(10, ("found bitmap at %d %d", i, j));
xrdp_bitmap_delete(bitmap);
return MAKELONG(j, i);
}
}
cache_id = 2;
cache_entries = self->cache3_entries;
}
else
{
log_message(LOG_LEVEL_ERROR,"error in xrdp_cache_add_bitmap, too big(%d) bpp %d", bmp_size, bitmap->bpp);
log_message(LOG_LEVEL_ERROR, "error in xrdp_cache_add_bitmap, "
"too big(%d) bpp %d", bmp_size, bitmap->bpp);
return 0;
}
/* look for oldest */
cache_id = 0;
cache_idx = 0;
oldest = 0x7fffffff;
if (bmp_size <= self->cache1_size)
crc16 = bitmap->crc16;
ll = &(self->crc16[cache_id][crc16]);
for (jndex = 0; jndex < ll->count; jndex++)
{
i = 0;
for (j = 0; j < self->cache1_entries; j++)
cache_idx = list16_get_item(ll, jndex);
if (COMPARE_WITH_CRC32
(self->bitmap_items[cache_id][cache_idx].bitmap, bitmap))
{
if (self->bitmap_items[i][j].stamp < oldest)
{
oldest = self->bitmap_items[i][j].stamp;
cache_id = i;
cache_idx = j;
}
LLOGLN(10, ("found bitmap at %d %d", index, jndex));
found = 1;
break;
}
}
else if (bmp_size <= self->cache2_size)
if (found)
{
i = 1;
lru_index = self->bitmap_items[cache_id][cache_idx].lru_index;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
xrdp_bitmap_delete(bitmap);
for (j = 0; j < self->cache2_entries; j++)
{
if (self->bitmap_items[i][j].stamp < oldest)
{
oldest = self->bitmap_items[i][j].stamp;
cache_id = i;
cache_idx = j;
}
}
/* update lru to end */
xrdp_cache_update_lru(self, cache_id, lru_index);
return MAKELONG(cache_idx, cache_id);
}
else if (bmp_size <= self->cache3_size)
/* find lru */
/* check for reset */
if (self->lru_reset[cache_id])
{
i = 2;
self->lru_reset[cache_id] = 0;
LLOGLN(0, ("xrdp_cache_add_bitmap: reset detected cache_id %d",
cache_id));
self->lru_tail[cache_id] = cache_entries - 1;
index = self->lru_tail[cache_id];
llru = &(self->bitmap_lrus[cache_id][index]);
llru->next = -1;
}
/* lru is item at head */
lru_index = self->lru_head[cache_id];
cache_idx = lru_index;
/* update lru to end */
xrdp_cache_update_lru(self, cache_id, lru_index);
LLOGLN(10, ("xrdp_cache_add_bitmap: oldest %d %d", cache_id, cache_idx));
LLOGLN(10, ("adding bitmap at %d %d old ptr %p new ptr %p",
cache_id, cache_idx,
self->bitmap_items[cache_id][cache_idx].bitmap,
bitmap));
for (j = 0; j < self->cache3_entries; j++)
/* remove old, about to be deleted, from crc16 list */
lbm = self->bitmap_items[cache_id][cache_idx].bitmap;
if (lbm != 0)
{
crc16 = lbm->crc16;
ll = &(self->crc16[cache_id][crc16]);
iig = list16_index_of(ll, cache_idx);
if (iig == -1)
{
if (self->bitmap_items[i][j].stamp < oldest)
{
oldest = self->bitmap_items[i][j].stamp;
cache_id = i;
cache_idx = j;
}
LLOGLN(0, ("xrdp_cache_add_bitmap: error removing cache_idx"));
}
LLOGLN(10, ("xrdp_cache_add_bitmap: removing index %d from crc16 %d",
iig, crc16));
list16_remove_item(ll, iig);
xrdp_bitmap_delete(lbm);
}
LLOGLN(10, ("adding bitmap at %d %d ptr %p", cache_id, cache_idx,
self->bitmap_items[cache_id][cache_idx].bitmap));
/* set, send bitmap and return */
xrdp_bitmap_delete(self->bitmap_items[cache_id][cache_idx].bitmap);
self->bitmap_items[cache_id][cache_idx].bitmap = bitmap;
self->bitmap_items[cache_id][cache_idx].stamp = self->bitmap_stamp;
self->bitmap_items[cache_id][cache_idx].lru_index = lru_index;
/* add to crc16 list */
crc16 = bitmap->crc16;
ll = &(self->crc16[cache_id][crc16]);
list16_add_item(ll, cache_idx);
if (ll->count > 1)
{
LLOGLN(10, ("xrdp_cache_add_bitmap: count %d", ll->count));
}
if (self->use_bitmap_comp)
{

@ -0,0 +1,479 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2004-2014
*
* Licensed 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.
*
* Encoder
*/
#include "xrdp_encoder.h"
#include "xrdp.h"
#include "thread_calls.h"
#include "fifo.h"
#ifdef XRDP_RFXCODEC
#include "rfxcodec_encode.h"
#endif
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
do \
{ \
if (_level < LLOG_LEVEL) \
{ \
g_write("xrdp:xrdp_encoder [%10.10u]: ", g_time3()); \
g_writeln _args ; \
} \
} \
while (0)
#define JPG_CODEC 0
#define RFX_CODEC 1
/*****************************************************************************/
static int
process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc);
/**
* Init encoder
*
* @return 0 on success, -1 on failure
*****************************************************************************/
/* called from main thread */
int APP_CC
init_xrdp_encoder(struct xrdp_mm *self)
{
char buf[1024];
int pid;
if (self == 0)
{
return -1;
}
LLOGLN(0, ("init_xrdp_encoder: initing encoder codec_id %d", self->codec_id));
/* setup required FIFOs */
self->fifo_to_proc = fifo_create();
self->fifo_processed = fifo_create();
self->mutex = tc_mutex_create();
pid = g_getpid();
/* setup wait objects for signalling */
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_event_to_proc", pid);
self->xrdp_encoder_event_to_proc = g_create_wait_obj(buf);
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_event_processed", pid);
self->xrdp_encoder_event_processed = g_create_wait_obj(buf);
g_snprintf(buf, 1024, "xrdp_%8.8x_encoder_term", pid);
self->xrdp_encoder_term = g_create_wait_obj(buf);
switch (self->codec_id)
{
case 2:
self->process_enc = process_enc_jpg;
break;
case 3:
self->process_enc = process_enc_rfx;
#ifdef XRDP_RFXCODEC
self->codec_handle =
rfxcodec_encode_create(self->wm->screen->width,
self->wm->screen->height,
RFX_FORMAT_YUV, 0);
//RFX_FORMAT_BGRA, 0);
#endif
break;
default:
LLOGLN(0, ("init_xrdp_encoder: unknown codec_id %d",
self->codec_id));
break;
}
/* create thread to process messages */
tc_thread_create(proc_enc_msg, self);
return 0;
}
/**
* Deinit xrdp encoder
*****************************************************************************/
/* called from main thread */
void APP_CC
deinit_xrdp_encoder(struct xrdp_mm *self)
{
XRDP_ENC_DATA *enc;
XRDP_ENC_DATA_DONE *enc_done;
FIFO *fifo;
LLOGLN(0, ("deinit_xrdp_encoder: deiniting encoder"));
if (self == 0)
{
return;
}
if (self->in_codec_mode == 0)
{
return;
}
/* tell worker thread to shut down */
g_set_wait_obj(self->xrdp_encoder_term);
g_sleep(1000);
if (self->codec_id == 3)
{
#ifdef XRDP_RFXCODEC
rfxcodec_encode_destroy(self->codec_handle);
#endif
}
/* destroy wait objects used for signalling */
g_delete_wait_obj(self->xrdp_encoder_event_to_proc);
g_delete_wait_obj(self->xrdp_encoder_event_processed);
g_delete_wait_obj(self->xrdp_encoder_term);
/* cleanup fifo_to_proc */
fifo = self->fifo_to_proc;
if (fifo)
{
while (!fifo_is_empty(fifo))
{
enc = fifo_remove_item(fifo);
if (enc == 0)
{
continue;
}
g_free(enc->drects);
g_free(enc->crects);
g_free(enc);
}
fifo_delete(fifo);
}
/* cleanup fifo_processed */
fifo = self->fifo_processed;
if (fifo)
{
while (!fifo_is_empty(fifo))
{
enc_done = fifo_remove_item(fifo);
if (enc == 0)
{
continue;
}
g_free(enc_done->comp_pad_data);
g_free(enc_done);
}
fifo_delete(fifo);
}
}
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc_jpg(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
int y;
int cx;
int cy;
int quality;
int error;
int out_data_bytes;
int count;
char *out_data;
XRDP_ENC_DATA_DONE *enc_done;
FIFO *fifo_processed;
tbus mutex;
tbus event_processed;
LLOGLN(10, ("process_enc_jpg:"));
quality = self->codec_quality;
fifo_processed = self->fifo_processed;
mutex = self->mutex;
event_processed = self->xrdp_encoder_event_processed;
count = enc->num_crects;
for (index = 0; index < count; index++)
{
x = enc->crects[index * 4 + 0];
y = enc->crects[index * 4 + 1];
cx = enc->crects[index * 4 + 2];
cy = enc->crects[index * 4 + 3];
if (cx < 1 || cy < 1)
{
LLOGLN(0, ("process_enc_jpg: error 1"));
continue;
}
LLOGLN(10, ("process_enc_jpg: x %d y %d cx %d cy %d", x, y, cx, cy));
out_data_bytes = MAX((cx + 4) * cy * 4, 8192);
if ((out_data_bytes < 1) || (out_data_bytes > 16 * 1024 * 1024))
{
LLOGLN(0, ("process_enc_jpg: error 2"));
return 1;
}
out_data = (char *) g_malloc(out_data_bytes + 256 + 2, 0);
if (out_data == 0)
{
LLOGLN(0, ("process_enc_jpg: error 3"));
return 1;
}
out_data[256] = 0; /* header bytes */
out_data[257] = 0;
error = libxrdp_codec_jpeg_compress(self->wm->session, 0, enc->data,
enc->width, enc->height,
enc->width * 4, x, y, cx, cy,
quality,
out_data + 256 + 2, &out_data_bytes);
if (error < 0)
{
LLOGLN(0, ("process_enc_jpg: jpeg error %d bytes %d",
error, out_data_bytes));
g_free(out_data);
return 1;
}
LLOGLN(10, ("jpeg error %d bytes %d", error, out_data_bytes));
enc_done = (XRDP_ENC_DATA_DONE *)
g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
enc_done->comp_bytes = out_data_bytes + 2;
enc_done->pad_bytes = 256;
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = index == (enc->num_crects - 1);
enc_done->x = x;
enc_done->y = y;
enc_done->cx = cx;
enc_done->cy = cy;
/* done with msg */
/* inform main thread done */
tc_mutex_lock(mutex);
fifo_add_item(fifo_processed, enc_done);
tc_mutex_unlock(mutex);
/* signal completion for main thread */
g_set_wait_obj(event_processed);
}
return 0;
}
#ifdef XRDP_RFXCODEC
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
int index;
int x;
int y;
int cx;
int cy;
int out_data_bytes;
int count;
int error;
char *out_data;
XRDP_ENC_DATA_DONE *enc_done;
FIFO *fifo_processed;
tbus mutex;
tbus event_processed;
struct rfx_tile *tiles;
struct rfx_rect *rfxrects;
LLOGLN(10, ("process_enc_rfx:"));
LLOGLN(10, ("process_enc_rfx: num_crects %d num_drects %d",
enc->num_crects, enc->num_drects));
fifo_processed = self->fifo_processed;
mutex = self->mutex;
event_processed = self->xrdp_encoder_event_processed;
if ((enc->num_crects > 512) || (enc->num_drects > 512))
{
return 0;
}
out_data_bytes = 16 * 1024 * 1024;
index = 256 + sizeof(struct rfx_tile) * 512 +
sizeof(struct rfx_rect) * 512;
out_data = (char *) g_malloc(out_data_bytes + index, 0);
if (out_data == 0)
{
return 0;
}
tiles = (struct rfx_tile *) (out_data + out_data_bytes + 256);
rfxrects = (struct rfx_rect *) (tiles + 512);
count = enc->num_crects;
for (index = 0; index < count; index++)
{
x = enc->crects[index * 4 + 0];
y = enc->crects[index * 4 + 1];
cx = enc->crects[index * 4 + 2];
cy = enc->crects[index * 4 + 3];
LLOGLN(10, ("process_enc_rfx:"));
tiles[index].x = x;
tiles[index].y = y;
tiles[index].cx = cx;
tiles[index].cy = cy;
LLOGLN(10, ("x %d y %d cx %d cy %d", x, y, cx, cy));
tiles[index].quant_y = 0;
tiles[index].quant_cb = 0;
tiles[index].quant_cr = 0;
}
count = enc->num_drects;
for (index = 0; index < count; index++)
{
x = enc->drects[index * 4 + 0];
y = enc->drects[index * 4 + 1];
cx = enc->drects[index * 4 + 2];
cy = enc->drects[index * 4 + 3];
LLOGLN(10, ("process_enc_rfx:"));
rfxrects[index].x = x;
rfxrects[index].y = y;
rfxrects[index].cx = cx;
rfxrects[index].cy = cy;
}
error = rfxcodec_encode(self->codec_handle, out_data + 256, &out_data_bytes,
enc->data, enc->width, enc->height, enc->width * 4,
rfxrects, enc->num_drects,
tiles, enc->num_crects, 0, 0);
LLOGLN(10, ("process_enc_rfx: rfxcodec_encode rv %d", error));
enc_done = (XRDP_ENC_DATA_DONE *)
g_malloc(sizeof(XRDP_ENC_DATA_DONE), 1);
enc_done->comp_bytes = out_data_bytes;
enc_done->pad_bytes = 256;
enc_done->comp_pad_data = out_data;
enc_done->enc = enc;
enc_done->last = 1;
enc_done->cx = self->wm->screen->width;
enc_done->cy = self->wm->screen->height;
/* done with msg */
/* inform main thread done */
tc_mutex_lock(mutex);
fifo_add_item(fifo_processed, enc_done);
tc_mutex_unlock(mutex);
/* signal completion for main thread */
g_set_wait_obj(event_processed);
return 0;
}
#else
/*****************************************************************************/
/* called from encoder thread */
static int
process_enc_rfx(struct xrdp_mm *self, XRDP_ENC_DATA *enc)
{
return 0;
}
#endif
/**
* Encoder thread main loop
*****************************************************************************/
THREAD_RV THREAD_CC
proc_enc_msg(void *arg)
{
XRDP_ENC_DATA *enc;
FIFO *fifo_to_proc;
tbus mutex;
tbus event_to_proc;
tbus term_obj;
tbus lterm_obj;
int robjs_count;
int wobjs_count;
int cont;
int timeout;
tbus robjs[32];
tbus wobjs[32];
struct xrdp_mm *self;
LLOGLN(0, ("proc_enc_msg: thread is running"));
self = (struct xrdp_mm *) arg;
if (self == 0)
{
LLOGLN(0, ("proc_enc_msg: self nil"));
return 0;
}
fifo_to_proc = self->fifo_to_proc;
mutex = self->mutex;
event_to_proc = self->xrdp_encoder_event_to_proc;
term_obj = g_get_term_event();
lterm_obj = self->xrdp_encoder_term;
cont = 1;
while (cont)
{
timeout = -1;
robjs_count = 0;
wobjs_count = 0;
robjs[robjs_count++] = term_obj;
robjs[robjs_count++] = lterm_obj;
robjs[robjs_count++] = event_to_proc;
if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0)
{
/* error, should not get here */
g_sleep(100);
}
if (g_is_wait_obj_set(term_obj)) /* global term */
{
LLOGLN(0, ("proc_enc_msg: global term"));
break;
}
if (g_is_wait_obj_set(lterm_obj)) /* xrdp_mm term */
{
LLOGLN(0, ("proc_enc_msg: xrdp_mm term"));
break;
}
if (g_is_wait_obj_set(event_to_proc))
{
/* clear it right away */
g_reset_wait_obj(event_to_proc);
/* get first msg */
tc_mutex_lock(mutex);
enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo_to_proc);
tc_mutex_unlock(mutex);
while (enc != 0)
{
/* do work */
self->process_enc(self, enc);
/* get next msg */
tc_mutex_lock(mutex);
enc = (XRDP_ENC_DATA *) fifo_remove_item(fifo_to_proc);
tc_mutex_unlock(mutex);
}
}
} /* end while (cont) */
LLOGLN(0, ("proc_enc_msg: thread exit"));
return 0;
}

@ -0,0 +1,16 @@
#ifndef _XRDP_ENCODER_H
#define _XRDP_ENCODER_H
#include "arch.h"
struct xrdp_mm;
int APP_CC
init_xrdp_encoder(struct xrdp_mm *self);
void APP_CC
deinit_xrdp_encoder(struct xrdp_mm *self);
THREAD_RV THREAD_CC
proc_enc_msg(void *arg);
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -0,0 +1,105 @@
#
# RDP Keyboard <-> X11 Keyboard layout map
#
# How this file works:
# 1. load the file and scan each section to find matching "keyboard_type"
# and "keyboard_subtype" based on the values received from the client.
# If not found, then jump to default section.
# 2. in the selected section, look for "rdp_layouts" and "layouts_map".
# Based on the "keylayout" value from the client, find the right x11
# layout value.
# 3. model/variant are inferred based on the "keyboard_type" and
# "keyboard_subtype", but they can be overridden.
#
#
# RDP Keyboard Type (http://msdn.microsoft.com/en-us/library/cc240563.aspx)
#
# 0 is not a valid value
#
# 1 - IBM PC/XT or compatible (83-key) keyboard
# 2 - Olivetti "ICO" (102-key) keyboard
# 3 - IBM PC/AT (84-key) or similar keyboard
# 4 - IBM enhanced (101- or 102-key) keyboard
# 5 - Nokia 1050 and similar keyboards
# 6 - Nokia 9140 and similar keyboards
# 7 - Japanese keyboard
#
# RDP Keyboard Subtype is vendor dependent. XRDP defines as follows:
#
# 0 is not a valid value
#
# 1 - Standard
# 2 - FreeRDP JP keyboard
# 3 - Macintosh
# ... - < any vendor dependent subtype >
#
# The list can be augmented.
#
# default
[default]
# keyboard_type and keyboard_subtype is not readed for default section. It
# is only as a place holder to keep consistency. Default model/variant are
# platform dependent, and could be overridden if needed.
keyboard_type=0
keyboard_subtype=0
# user could override variant and model, but generally they should be inferred
# automatically based on keyboard type and subtype
#variant=
#model=
# A list of supported RDP keyboard layouts
rdp_layouts=default_rdp_layouts
# The map from RDP keyboard layout to X11 keyboard layout
layouts_map=default_layouts_map
[default_rdp_layouts]
rdp_layout_us=0x00000409
rdp_layout_de=0x00000407
rdp_layout_fr=0x0000040C
rdp_layout_it=0x00000410
rdp_layout_jp=0x00000411
rdp_layout_ru=0x00000419
rdp_layout_se=0x0000041D
rdp_layout_pt=0x00000816
rdp_layout_br=0x00000416
# <rdp layout name> = <X11 keyboard layout value>
[default_layouts_map]
rdp_layout_us=us
rdp_layout_de=de
rdp_layout_fr=fr
rdp_layout_it=it
rdp_layout_jp=jp
rdp_layout_ru=ru
rdp_layout_se=se
rdp_layout_pt=pt
rdp_layout_br=br(abnt2)
# if two sections have the same keyboard_type and keyboard_subtype, then
# the latter could override the former.
[rdp_keyboard_mac]
keyboard_type=4
keyboard_subtype=3
rdp_layouts=default_rdp_layouts
layouts_map=rdp_layouts_map_mac
[rdp_keyboard_jp]
keyboard_type=7
keyboard_subtype=2
rdp_layouts=default_rdp_layouts
layouts_map=default_layouts_map
[rdp_layouts_map_mac]
rdp_layout_us=us
rdp_layout_de=de
rdp_layout_fr=fr
rdp_layout_jp=jp
rdp_layout_it=it
rdp_layout_ru=ru
rdp_layout_se=se
rdp_layout_pt=pt
rdp_layout_br=br(abnt2)

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -60,6 +60,7 @@ xrdp_listen_create(void)
g_process_sem = tc_sem_create(0);
}
/* setting TCP mode now, may change later */
self->listen_trans = trans_create(TRANS_MODE_TCP, 16, 16);
if (self->listen_trans == 0)
@ -168,7 +169,7 @@ xrdp_listen_get_port_address(char *port, int port_bytes,
*tcp_nodelay = 0 ;
*tcp_keepalive = 0 ;
if (fd > 0)
if (fd != -1)
{
names = list_create();
names->auto_free = 1;
@ -186,12 +187,18 @@ xrdp_listen_get_port_address(char *port, int port_bytes,
if (g_strcasecmp(val, "port") == 0)
{
val = (char *)list_get_item(values, index);
error = g_atoi(val);
if ((error > 0) && (error < 65000))
if (val[0] == '/')
{
g_strncpy(port, val, port_bytes - 1);
}
else
{
error = g_atoi(val);
if ((error > 0) && (error < 65000))
{
g_strncpy(port, val, port_bytes - 1);
}
}
}
if (g_strcasecmp(val, "address") == 0)
@ -235,9 +242,11 @@ xrdp_listen_get_port_address(char *port, int port_bytes,
list_delete(names);
list_delete(values);
g_file_close(fd);
}
if (fd != -1)
g_file_close(fd);
/* startup_param overrides */
if (startup_param->port[0] != 0)
{
@ -348,7 +357,15 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
return 1;
}
/*Create socket*/
if (port[0] == '/')
{
/* set UDS mode */
self->listen_trans->mode = TRANS_MODE_UNIX;
/* not valid with UDS */
tcp_nodelay = 0;
}
/* Create socket */
error = trans_listen_address(self->listen_trans, port, address);
if (error == 0)
@ -433,7 +450,7 @@ xrdp_listen_main_loop(struct xrdp_listen *self)
robjs[robjs_count++] = done_obj;
timeout = -1;
if (self->listen_trans != 0)
/* if (self->listen_trans != 0) */
{
if (trans_get_wait_objs(self->listen_trans, robjs,
&robjs_count) != 0)

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -242,6 +242,89 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap *wnd)
return 0;
}
/*****************************************************************************/
/**
* This is an internal function in this file used to parse the domain
* information sent from the client. If the information starts
* with '_' the domain field contains the IP/DNS to connect to.
* If the domain field contains an additional '__' the char that
* follows this '__' is an index number of a preferred combo choice.
* Valid values for this choice is 0-9. But this function will only return
* index numbers between 0 and the max number of combo items -1.
* Example: _192.168.1.2__1 result in a resultbuffer containing
* 192.168.1.2 and the return value will be 1. Meaning that
* index 1 is the preferred combo choice.
*
* Users can create shortcuts where this information is configured. These
* shortcuts simplifies login.
* @param orginalDomainInfo indata to this function
* @param comboMax the max number of combo choices
* @param decode if true then we perform decoding of combo choice
* @param resultBuffer must be pre allocated before calling this function.
* Holds the IP. The size of this buffer must be 256 bytes
* @return the index number of the combobox that the user prefer.
* 0 if the user does not prefer any choice.
*/
static int APP_CC
xrdp_wm_parse_domain_information(char *orginalDomainInfo, int comboMax,
int decode, char *resultBuffer)
{
int ret;
int pos;
int comboxindex;
char index[2];
char debugstr[256];
/* If the first char in the domain name is '_' we use the domain
name as IP*/
ret = 0; /* default return value */
/* resultBuffer assumed to be 256 chars */
g_memset(resultBuffer, 0, 256);
if (orginalDomainInfo[0] == '_')
{
/* we try to locate a number indicating what combobox index the user
* prefer the information is loaded from domain field, from the client
* log_message(LOG_LEVEL_DEBUG, "domain contains _");
* We must use valid chars in the domain name.
* Underscore is a valid name in the domain.
* Invalid chars are ignored in microsoft client therefore we use '_'
* again. this sec '__' contains the split for index.*/
pos = g_pos(&orginalDomainInfo[1], "__");
if (pos > 0)
{
/* an index is found we try to use it
log_message(LOG_LEVEL_DEBUG, "domain contains index char __");*/
if (decode)
{
g_memset(index, 0, 2);
/* we just accept values 0-9 (one figure) */
g_strncpy(index, &orginalDomainInfo[pos + 3], 1);
comboxindex = g_htoi(index);
g_snprintf(debugstr, 255, "Value of index (as char): %s "
"(converted) : %d (max) : %d", index, comboxindex,
comboMax - 1);
debugstr[255] = 0;
log_message(LOG_LEVEL_DEBUG, debugstr);
/* limit to max number of items in combo box */
if ((comboxindex > 0) && (comboxindex < comboMax))
{
log_message(LOG_LEVEL_DEBUG, "domain contains a valid "
"index number");
ret = comboxindex; /* preferred index for combo box. */
}
}
/* pos limit the String to only contain the IP */
g_strncpy(resultBuffer, &orginalDomainInfo[1], pos);
}
else
{
/* log_message(LOG_LEVEL_DEBUG, "domain does not contain _"); */
g_strncpy(resultBuffer, &orginalDomainInfo[1], 255);
}
}
return ret;
}
/******************************************************************************/
static int APP_CC
xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
@ -255,6 +338,7 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
struct xrdp_mod_data *mod;
struct xrdp_bitmap *b;
struct xrdp_cfg_globals *globals;
char resultIP[256];
globals = &self->xrdp_config->cfg_globals;
@ -269,7 +353,7 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
}
insert_index = list_index_of(self->login_window->child_list,
(long)combo);
(long)combo); /* find combo in the list */
insert_index++;
mod = (struct xrdp_mod_data *)
list_get_item(combo->data_list, combo->item_index);
@ -322,19 +406,26 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
{
self->login_window->focused_control = b;
}
/*Use the domain name as the destination IP/DNS
This is useful in a gateway setup.*/
if (g_strncmp(name, "ip", 255) == 0)
{
/* If the first char in the domain name is '_' we use the domain name as IP*/
if(self->session->client_info->domain[0]=='_')
{
g_strncpy(b->caption1, &self->session->client_info->domain[1], 255);
b->edit_pos = g_mbstowcs(0, b->caption1, 0);
}
}
if (g_strncmp(name, "username", 255) == 0)
/* Use the domain name as the destination IP/DNS
This is useful in a gateway setup. */
if (g_strncmp(name, "ip", 255) == 0)
{
/* If the first char in the domain name is '_' we use the
domain name as IP */
if (self->session->client_info->domain[0] == '_')
{
xrdp_wm_parse_domain_information(
self->session->client_info->domain,
combo->data_list->count, 0, resultIP);
g_strncpy(b->caption1, resultIP, 255);
b->edit_pos = g_mbstowcs(0, b->caption1, 0);
}
}
if (g_strncmp(name, "username", 255) == 0 &&
self->session->client_info->username[0])
{
g_strncpy(b->caption1, self->session->client_info->username, 255);
b->edit_pos = g_mbstowcs(0, b->caption1, 0);
@ -456,9 +547,13 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
if (fd < 1)
if (fd < 0)
{
log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s", cfg_file);
list_delete(sections);
list_delete(section_names);
list_delete(section_values);
return 1;
}
file_read_sections(fd, sections);
@ -519,6 +614,7 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
char buf[256];
char buf1[256];
char resultIP[256];
int log_width;
int log_height;
int regular;
@ -559,12 +655,39 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
self->login_window->notify = xrdp_wm_login_notify;
g_gethostname(buf1, 256);
g_sprintf(buf, "Login to %s", buf1);
set_string(&self->login_window->caption1, buf);
/* if window title not specified, use hostname as default */
if (globals->ls_title[0] == 0)
{
g_gethostname(buf1, 256);
g_sprintf(buf, "Login to %s", buf1);
set_string(&self->login_window->caption1, buf);
}
else
{
/*self->login_window->caption1 = globals->ls_title[0];*/
g_sprintf(buf, "%s", globals->ls_title);
set_string(&self->login_window->caption1, buf);
}
if (regular)
{
/* Load the background image. */
/* If no file is specified no default image will be loaded. */
/* We only load the image if bpp > 8 */
if (globals->ls_background_image[0] != 0 && self->screen->bpp > 8)
{
char fileName[256] ;
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
g_snprintf(fileName, 255, "%s/%s", XRDP_SHARE_PATH, globals->ls_background_image);
log_message(LOG_LEVEL_DEBUG, "We try to load the following background file: %s", fileName);
xrdp_bitmap_load(but, fileName, self->palette);
but->parent = self->screen;
but->owner = self->screen;
but->left = self->screen->width - but->width;
but->top = self->screen->height - but->height;
list_add_item(self->screen->child_list, (long)but);
}
/* if logo image not specified, use default */
if (globals->ls_logo_filename[0] == 0)
g_snprintf(globals->ls_logo_filename, 255, "%s/xrdp_logo.bmp", XRDP_SHARE_PATH);
@ -631,7 +754,14 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
but->tab_stop = 1;
self->login_window->esc_button = but;
/* labels and edits */
/* labels and edits.
* parameter: 1 = decode domain field index information from client.
* We only perform this the first time for each connection.
*/
combo->item_index = xrdp_wm_parse_domain_information(
self->session->client_info->domain,
combo->data_list->count, 1,
resultIP /* just a dummy place holder, we ignore */ );
xrdp_wm_show_edits(self, combo);
return 0;
@ -826,12 +956,22 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
else if (g_strncmp(n, "ls_bg_color", 64) == 0)
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
else if (g_strncmp(n, "ls_title", 255) == 0)
{
g_strncpy(globals->ls_title, v, 255);
globals->ls_title[255] = 0;
}
else if (g_strncmp(n, "ls_logo_filename", 255) == 0)
{
g_strncpy(globals->ls_logo_filename, v, 255);
globals->ls_logo_filename[255] = 0;
}
else if (g_strncmp(n, "ls_background_image", 255) == 0)
{
g_strncpy(globals->ls_background_image, v, 255);
globals->ls_background_image[255] = 0;
}
else if (g_strncmp(n, "ls_logo_x_pos", 64) == 0)
globals->ls_logo_x_pos = g_atoi(v);
@ -916,6 +1056,7 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
g_writeln("ls_width: %d", globals->ls_width);
g_writeln("ls_height: %d", globals->ls_height);
g_writeln("ls_bg_color: %x", globals->ls_bg_color);
g_writeln("ls_title: %s", globals->ls_title);
g_writeln("ls_logo_filename: %s", globals->ls_logo_filename);
g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos);
g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos);

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,7 +18,9 @@
* module manager
*/
#if defined(HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#define ACCESS
#include "xrdp.h"
#include "log.h"
@ -28,6 +30,20 @@
#endif
#endif
#include "xrdp_encoder.h"
#define LLOG_LEVEL 1
#define LLOGLN(_level, _args) \
do \
{ \
if (_level < LLOG_LEVEL) \
{ \
g_write("xrdp:xrdp_mm [%10.10u]: ", g_time3()); \
g_writeln _args ; \
} \
} \
while (0)
/*****************************************************************************/
struct xrdp_mm *APP_CC
xrdp_mm_create(struct xrdp_wm *owner)
@ -40,6 +56,49 @@ xrdp_mm_create(struct xrdp_wm *owner)
self->login_names->auto_free = 1;
self->login_values = list_create();
self->login_values->auto_free = 1;
LLOGLN(0, ("xrdp_mm_create: bpp %d mcs_connection_type %d "
"jpeg_codec_id %d v3_codec_id %d rfx_codec_id %d",
self->wm->client_info->bpp,
self->wm->client_info->mcs_connection_type,
self->wm->client_info->jpeg_codec_id,
self->wm->client_info->v3_codec_id,
self->wm->client_info->rfx_codec_id));
/* go into jpeg codec mode if jpeg set, lan set */
if (self->wm->client_info->mcs_connection_type == 6) /* LAN */
{
if (self->wm->client_info->jpeg_codec_id == 2) /* JPEG */
{
if (self->wm->client_info->bpp > 16)
{
LLOGLN(0, ("xrdp_mm_create: starting jpeg codec session"));
self->codec_id = 2;
self->in_codec_mode = 1;
self->codec_quality = self->wm->client_info->jpeg_prop[0];
self->wm->client_info->capture_code = 0;
self->wm->client_info->capture_format =
/* PIXMAN_a8b8g8r8 */
(32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8;
}
}
else if (self->wm->client_info->rfx_codec_id == 3) /* RFX */
{
if (self->wm->client_info->bpp > 16)
{
LLOGLN(0, ("xrdp_mm_create: starting rfx codec session"));
self->codec_id = 3;
self->in_codec_mode = 1;
self->wm->client_info->capture_code = 2;
}
}
}
if (self->in_codec_mode)
{
/* setup thread to handle codec mode messages */
init_xrdp_encoder(self);
}
return self;
}
@ -68,7 +127,7 @@ xrdp_mm_sync_load(long param1, long param2)
static void APP_CC
xrdp_mm_module_cleanup(struct xrdp_mm *self)
{
log_message(LOG_LEVEL_DEBUG,"xrdp_mm_module_cleanup");
log_message(LOG_LEVEL_DEBUG, "xrdp_mm_module_cleanup");
if (self->mod != 0)
{
@ -92,6 +151,14 @@ xrdp_mm_module_cleanup(struct xrdp_mm *self)
self->mod_exit = 0;
self->mod = 0;
self->mod_handle = 0;
if (self->wm->hide_log_window)
{
/* make sure autologin is off */
self->wm->session->client_info->rdp_autologin = 0;
xrdp_wm_set_login_mode(self->wm, 0); /* reset session */
}
}
/*****************************************************************************/
@ -105,6 +172,10 @@ xrdp_mm_delete(struct xrdp_mm *self)
/* free any module stuff */
xrdp_mm_module_cleanup(self);
/* shutdown thread */
deinit_xrdp_encoder(self);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
self->sesman_trans_up = 0;
@ -151,7 +222,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
}
else if (g_strcasecmp(name, "code") == 0)
{
/* this code is either 0 for Xvnc or 10 for X11rdp */
/* this code is either 0 for Xvnc, 10 for X11rdp or 20 for Xorg */
self->code = g_atoi(value);
}
else if (g_strcasecmp(name, "xserverbpp") == 0)
@ -168,7 +239,7 @@ xrdp_mm_send_login(struct xrdp_mm *self)
s = trans_get_out_s(self->sesman_trans, 8192);
s_push_layer(s, channel_hdr, 8);
/* this code is either 0 for Xvnc or 10 for X11rdp */
/* this code is either 0 for Xvnc, 10 for X11rdp or 20 for Xorg */
out_uint16_be(s, self->code);
index = g_strlen(username);
out_uint16_be(s, index);
@ -465,7 +536,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
{
g_snprintf(text, 255, "%d", 5900 + self->display);
}
else if (self->code == 10) /* X11rdp */
else if (self->code == 10 || self->code == 20) /* X11rdp/Xorg */
{
use_uds = 1;
@ -479,7 +550,7 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
if (use_uds)
{
g_snprintf(text, 255, "/tmp/.xrdp/xrdp_display_%d", self->display);
g_snprintf(text, 255, XRDP_X11RDP_STR, self->display);
}
else
{
@ -526,6 +597,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self)
{
rv = 0; /* connect success */
}
else
{
xrdp_wm_show_log(self->wm);
}
}
if (rv == 0)
@ -1157,9 +1232,9 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
self->wm->dragging = 0;
/* connect channel redir */
if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
if ((g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{
g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", 7200 + display);
g_snprintf(port, 255, XRDP_CHANSRV_STR, display);
}
else
{
@ -1176,6 +1251,7 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
"login failed");
log_message(LOG_LEVEL_INFO,"xrdp_mm_process_login_response: "
"login failed");
xrdp_wm_show_log(self->wm);
}
cleanup_sesman_connection(self);
@ -1234,9 +1310,11 @@ xrdp_mm_get_sesman_port(char *port, int port_bytes)
list_delete(names);
list_delete(values);
g_file_close(fd);
}
if (fd != -1)
g_file_close(fd);
return 0;
}
@ -1361,7 +1439,7 @@ access_control(char *username, char *password, char *srv)
int index;
int socket = g_tcp_socket();
if (socket > 0)
if (socket != -1)
{
/* we use a blocking socket here */
reply = g_tcp_connect(socket, srv, "3350");
@ -1454,6 +1532,9 @@ access_control(char *username, char *password, char *srv)
log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
}
if (socket != -1)
g_tcp_close(socket);
return rec;
}
#endif
@ -1473,7 +1554,7 @@ cleanup_states(struct xrdp_mm *self)
self-> sesman_trans_up = 0; /* true once connected to sesman */
self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
self-> code = 0; /* 0 Xvnc session 10 X11rdp session */
self-> code = 0; /* 0 Xvnc session, 10 X11rdp session, 20 Xorg session */
self-> sesman_controlled = 0; /* true if this is a sesman session */
self-> chan_trans = NULL; /* connection to chansrv */
self-> chan_trans_up = 0; /* true once connected to chansrv */
@ -1875,14 +1956,79 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self,
}
}
if (self->in_codec_mode)
{
read_objs[(*rcount)++] = self->xrdp_encoder_event_processed;
}
return rv;
}
#define DUMP_JPEG 0
#if DUMP_JPEG
/*****************************************************************************/
static int APP_CC
xrdp_mm_dump_jpeg(struct xrdp_mm *self, XRDP_ENC_DATA_DONE *enc_done)
{
static tbus ii;
static int jj;
struct _header
{
char tag[4];
int width;
int height;
int bytes_follow;
} header;
tui16 *pheader_bytes;
int cx;
int cy;
pheader_bytes = (tui16 *) (enc_done->comp_pad_data + enc_done->pad_bytes);
cx = enc_done->enc->crects[enc_done->index * 4 + 2];
cy = enc_done->enc->crects[enc_done->index * 4 + 3];
header.tag[0] = 'B';
header.tag[1] = 'E';
header.tag[2] = 'E';
header.tag[3] = 'F';
header.width = cx;
header.height = cy;
header.bytes_follow = enc_done->comp_bytes - (2 + pheader_bytes[0]);
if (ii == 0)
{
ii = g_file_open("/tmp/jpeg.beef.bin");
if (ii == -1)
{
ii = 0;
}
}
if (ii != 0)
{
g_file_write(ii, (char*)&header, sizeof(header));
g_file_write(ii, enc_done->comp_pad_data +
enc_done->pad_bytes + 2 + pheader_bytes[0],
enc_done->comp_bytes - (2 + pheader_bytes[0]));
jj++;
g_writeln("dumping jpeg index %d", jj);
}
return 0;
}
#endif
/*****************************************************************************/
int APP_CC
xrdp_mm_check_wait_objs(struct xrdp_mm *self)
{
XRDP_ENC_DATA_DONE *enc_done;
int rv;
int x;
int y;
int cx;
int cy;
if (self == 0)
{
@ -1931,6 +2077,59 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self)
self->delete_chan_trans = 0;
}
if (self->in_codec_mode)
{
if (g_is_wait_obj_set(self->xrdp_encoder_event_processed))
{
g_reset_wait_obj(self->xrdp_encoder_event_processed);
tc_mutex_lock(self->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
fifo_remove_item(self->fifo_processed);
tc_mutex_unlock(self->mutex);
while (enc_done != 0)
{
/* do something with msg */
LLOGLN(10, ("xrdp_mm_check_wait_objs: message back bytes %d",
enc_done->comp_bytes));
x = enc_done->x;
y = enc_done->y;
cx = enc_done->cx;
cy = enc_done->cy;
#if DUMP_JPEG
xrdp_mm_dump_jpeg(self, enc_done);
#endif
if (enc_done->comp_bytes > 0)
{
libxrdp_fastpath_send_surface(self->wm->session,
enc_done->comp_pad_data,
enc_done->pad_bytes,
enc_done->comp_bytes,
x, y, x + cx, y + cy,
32, self->codec_id, cx, cy);
}
/* free enc_done */
if (enc_done->last)
{
LLOGLN(10, ("xrdp_mm_check_wait_objs: last set"));
self->mod->mod_frame_ack(self->mod,
enc_done->enc->flags, enc_done->enc->frame_id);
g_free(enc_done->enc->drects);
g_free(enc_done->enc->crects);
g_free(enc_done->enc);
}
g_free(enc_done->comp_pad_data);
g_free(enc_done);
tc_mutex_lock(self->mutex);
enc_done = (XRDP_ENC_DATA_DONE*)
fifo_remove_item(self->fifo_processed);
tc_mutex_unlock(self->mutex);
}
}
}
return rv;
}
@ -2140,17 +2339,78 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
/*****************************************************************************/
int DEFAULT_CC
server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags)
int num_crects, short *crects, char *data, int width,
int height, int flags, int frame_id)
{
struct xrdp_wm* wm;
struct xrdp_mm* mm;
struct xrdp_painter* p;
struct xrdp_bitmap *b;
short *s;
int index;
XRDP_ENC_DATA *enc_data;
//g_writeln("server_paint_rects:");
wm = (struct xrdp_wm*)(mod->wm);
mm = wm->mm;
LLOGLN(10, ("server_paint_rects:"));
LLOGLN(10, ("server_paint_rects: %d", mm->in_codec_mode));
if (mm->in_codec_mode)
{
/* copy formal params to XRDP_ENC_DATA */
enc_data = (XRDP_ENC_DATA *) g_malloc(sizeof(XRDP_ENC_DATA), 1);
if (enc_data == 0)
{
return 1;
}
enc_data->drects = (short *)
g_malloc(sizeof(short) * num_drects * 4, 0);
if (enc_data->drects == 0)
{
g_free(enc_data);
return 1;
}
enc_data->crects = (short *)
g_malloc(sizeof(short) * num_crects * 4, 0);
if (enc_data->crects == 0)
{
g_free(enc_data->drects);
g_free(enc_data);
return 1;
}
g_memcpy(enc_data->drects, drects, sizeof(short) * num_drects * 4);
g_memcpy(enc_data->crects, crects, sizeof(short) * num_crects * 4);
enc_data->mod = mod;
enc_data->num_drects = num_drects;
enc_data->num_crects = num_crects;
enc_data->data = data;
enc_data->width = width;
enc_data->height = height;
enc_data->flags = flags;
enc_data->frame_id = frame_id;
if (width == 0 || height == 0)
{
LLOGLN(10, ("server_paint_rects: error"));
}
/* insert into fifo for encoder thread to process */
tc_mutex_lock(mm->mutex);
fifo_add_item(mm->fifo_to_proc, (void *) enc_data);
tc_mutex_unlock(mm->mutex);
/* signal xrdp_encoder thread */
g_set_wait_obj(mm->xrdp_encoder_event_to_proc);
return 0;
}
//g_writeln("server_paint_rects:");
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
@ -2166,6 +2426,7 @@ server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
s += 4;
}
xrdp_bitmap_delete(b);
mm->mod->mod_frame_ack(mm->mod, flags, frame_id);
return 0;
}
@ -2490,10 +2751,11 @@ int read_allowed_channel_names(struct list *names, struct list *values)
int ret = 0;
char cfg_file[256];
int pos;
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file);
if (fd > 0)
if (fd != -1)
{
names->auto_free = 1;
values->auto_free = 1;
@ -3045,4 +3307,3 @@ server_add_char_alpha(struct xrdp_mod* mod, int font, int charactor,
return libxrdp_orders_send_font(((struct xrdp_wm*)mod->wm)->session,
&fi, font, charactor);
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -848,9 +848,14 @@ xrdp_painter_copy(struct xrdp_painter *self,
while (i < (srcx + cx))
{
w = MIN(64, ((srcx + cx) - i));
h = MIN(64, ((srcy + cy) - j));
h = MIN(63, ((srcy + cy) - j));
b = xrdp_bitmap_create(w, h, src->bpp, 0, self->wm);
#if 1
xrdp_bitmap_copy_box_with_crc(src, b, i, j, w, h);
#else
xrdp_bitmap_copy_box(src, b, i, j, w, h);
xrdp_bitmap_hash_crc(b);
#endif
bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b, self->wm->hints);
cache_id = HIWORD(bitmap_id);
cache_idx = LOWORD(bitmap_id);
@ -878,7 +883,7 @@ xrdp_painter_copy(struct xrdp_painter *self,
i += 64;
}
j += 64;
j += 63;
}
xrdp_region_delete(region);

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -70,15 +70,15 @@ xrdp_process_loop(struct xrdp_process *self, struct stream *s)
if (self->session != 0)
{
rv = libxrdp_process_data(self->session, s);
}
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
{
DEBUG(("calling xrdp_wm_init and creating wm"));
self->wm = xrdp_wm_create(self, self->session->client_info);
/* at this point the wm(window manager) is create and wm::login_mode is
zero and login_mode_event is set so xrdp_wm_init should be called by
xrdp_wm_check_wait_objs */
if ((self->wm == 0) && (self->session->up_and_running) && (rv == 0))
{
DEBUG(("calling xrdp_wm_init and creating wm"));
self->wm = xrdp_wm_create(self, self->session->client_info);
/* at this point the wm(window manager) is create and wm::login_mode is
zero and login_mode_event is set so xrdp_wm_init should be called by
xrdp_wm_check_wait_objs */
}
}
return rv;
@ -114,62 +114,6 @@ xrdp_process_mod_end(struct xrdp_process *self)
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_process_get_pdu_bytes(const char *aheader)
{
int rv;
const tui8 *header;
rv = -1;
header = (const tui8 *) aheader;
if (header[0] == 0x03)
{
/* TPKT */
rv = (header[2] << 8) | header[3];
}
else if (header[0] == 0x30)
{
/* TSRequest (NLA) */
if (header[1] & 0x80)
{
if ((header[1] & ~(0x80)) == 1)
{
rv = header[2];
rv += 3;
}
else if ((header[1] & ~(0x80)) == 2)
{
rv = (header[2] << 8) | header[3];
rv += 4;
}
else
{
g_writeln("xrdp_process_get_packet_bytes: error TSRequest!");
return -1;
}
}
else
{
rv = header[1];
rv += 2;
}
}
else
{
/* Fast-Path */
if (header[1] & 0x80)
{
rv = ((header[1] & 0x7F) << 8) | header[2];
}
else
{
rv = header[1];
}
}
return rv;
}
/*****************************************************************************/
static int DEFAULT_CC
xrdp_process_data_in(struct trans *self)
@ -196,12 +140,13 @@ xrdp_process_data_in(struct trans *self)
{
pro->server_trans->extra_flags = 1;
pro->server_trans->header_size = 4;
init_stream(s, 0);
}
break;
case 1:
/* we have enough now to get the PDU bytes */
len = xrdp_process_get_pdu_bytes(s->p);
len = libxrdp_get_pdu_bytes(s->p);
if (len == -1)
{
g_writeln("xrdp_process_data_in: "
@ -226,7 +171,6 @@ xrdp_process_data_in(struct trans *self)
pro->server_trans->extra_flags = 1;
break;
}
return 0;
}
@ -258,6 +202,8 @@ xrdp_process_main_loop(struct xrdp_process *self)
if (libxrdp_process_incomming(self->session) == 0)
{
init_stream(self->server_trans->in_s, 32 * 1024);
term_obj = g_get_term_event();
cont = 1;

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@
#include "xrdp_rail.h"
#include "xrdp_constants.h"
#include "fifo.h"
#define MAX_NR_CHANNELS 16
#define MAX_CHANNEL_NAME 16
@ -46,7 +47,8 @@ struct xrdp_mod
int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct xrdp_mod* v);
long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id);
long mod_dumby[100 - 10]; /* align, 100 minus the number of mod
functions above */
/* server functions */
int (*server_begin_update)(struct xrdp_mod* v);
@ -142,7 +144,8 @@ struct xrdp_mod
int (*server_paint_rects)(struct xrdp_mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
char *data, int width, int height,
int flags, int frame_id);
long server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */
/* common */
@ -177,9 +180,16 @@ struct xrdp_palette_item
struct xrdp_bitmap_item
{
int stamp;
int lru_index;
struct xrdp_bitmap* bitmap;
};
struct xrdp_lru_item
{
int next;
int prev;
};
struct xrdp_os_bitmap_item
{
int id;
@ -225,6 +235,17 @@ struct xrdp_cache
int bitmap_stamp;
struct xrdp_bitmap_item bitmap_items[XRDP_MAX_BITMAP_CACHE_ID]
[XRDP_MAX_BITMAP_CACHE_IDX];
/* lru optimize */
struct xrdp_lru_item bitmap_lrus[XRDP_MAX_BITMAP_CACHE_ID]
[XRDP_MAX_BITMAP_CACHE_IDX];
int lru_head[XRDP_MAX_BITMAP_CACHE_ID];
int lru_tail[XRDP_MAX_BITMAP_CACHE_ID];
int lru_reset[XRDP_MAX_BITMAP_CACHE_ID];
/* crc optimize */
struct list16 crc16[XRDP_MAX_BITMAP_CACHE_ID][64 * 1024];
int use_bitmap_comp;
int cache1_entries;
int cache1_size;
@ -247,6 +268,9 @@ struct xrdp_cache
struct list* xrdp_os_del_list;
};
/* defined later */
struct xrdp_enc_data;
struct xrdp_mm
{
struct xrdp_wm* wm; /* owner */
@ -262,12 +286,25 @@ struct xrdp_mm
int (*mod_exit)(struct xrdp_mod*);
struct xrdp_mod* mod; /* module interface */
int display; /* 10 for :10.0, 11 for :11.0, etc */
int code; /* 0 Xvnc session 10 X11rdp session */
int code; /* 0=Xvnc session, 10=X11rdp session, 20=xorg driver mode */
int sesman_controlled; /* true if this is a sesman session */
struct trans* chan_trans; /* connection to chansrv */
int chan_trans_up; /* true once connected to chansrv */
int delete_chan_trans; /* boolean set when done with channel connection */
int usechansrv; /* true if chansrvport is set in xrdp.ini or using sesman */
/* for codec mode operations */
int in_codec_mode;
int codec_id;
int codec_quality;
tbus xrdp_encoder_event_to_proc;
tbus xrdp_encoder_event_processed;
tbus xrdp_encoder_term;
FIFO *fifo_to_proc;
FIFO *fifo_processed;
tbus mutex;
int (*process_enc)(struct xrdp_mm *self, struct xrdp_enc_data *enc);
void *codec_handle;
};
struct xrdp_key_info
@ -453,7 +490,8 @@ struct xrdp_bitmap
struct xrdp_bitmap* popped_from;
int item_height;
/* crc */
int crc;
int crc32;
int crc16;
};
#define NUM_FONTS 0x4e00
@ -547,6 +585,7 @@ struct xrdp_cfg_globals
int ls_height; /* window height */
int ls_bg_color; /* background color */
char ls_logo_filename[256]; /* logo filename */
char ls_background_image[256]; /* background image file name */
int ls_logo_x_pos; /* logo x co-ordinate */
int ls_logo_y_pos; /* logo y co-ordinate */
int ls_label_x_pos; /* x pos of labels */
@ -562,6 +601,7 @@ struct xrdp_cfg_globals
int ls_btn_cancel_y_pos; /* y pos for Cancel button */
int ls_btn_cancel_width; /* width of Cancel button */
int ls_btn_cancel_height; /* height of Cancel button */
char ls_title[256]; /* loginscreen window title */
};
struct xrdp_cfg_logging
@ -581,4 +621,39 @@ struct xrdp_config
struct xrdp_cfg_channels cfg_channels;
};
/* used when scheduling tasks in xrdp_encoder.c */
struct xrdp_enc_data
{
struct xrdp_mod *mod;
int num_drects;
short *drects; /* 4 * num_drects */
int num_crects;
short *crects; /* 4 * num_crects */
char *data;
int width;
int height;
int flags;
int frame_id;
};
typedef struct xrdp_enc_data XRDP_ENC_DATA;
/* used when scheduling tasks from xrdp_encoder.c */
struct xrdp_enc_data_done
{
int comp_bytes;
int pad_bytes;
char *comp_pad_data;
struct xrdp_enc_data *enc;
int last; /* true is this is last message for enc */
int x;
int y;
int cx;
int cy;
};
typedef struct xrdp_enc_data_done XRDP_ENC_DATA_DONE;
#endif

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -236,10 +236,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
init_stream(fs, 8192);
fd = g_file_open(file_name);
if (fd < 1)
if (fd < 0)
{
log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_pointer: error loading pointer from file [%s]",
file_name);
xstream_free(fs);
return 1;
}
@ -259,8 +260,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
{
if (bpp == 1)
{
in_uint8a(fs, palette, 8);
for (i = 0; i < 2; i++)
{
in_uint32_le(fs, pixel);
palette[i] = pixel;
}
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
@ -279,8 +283,11 @@ xrdp_wm_load_pointer(struct xrdp_wm *self, char *file_name, char *data,
}
else if (bpp == 4)
{
in_uint8a(fs, palette, 64);
for (i = 0; i < 16; i++)
{
in_uint32_le(fs, pixel);
palette[i] = pixel;
}
for (i = 0; i < 32; i++)
{
for (j = 0; j < 32; j++)
@ -540,17 +547,20 @@ xrdp_wm_init(struct xrdp_wm *self)
struct list *values;
char *q;
char *r;
char param[256];
char section_name[256];
char cfg_file[256];
char autorun_name[256];
g_writeln("in xrdp_wm_init: ");
load_xrdp_config(self->xrdp_config, self->screen->bpp);
xrdp_wm_load_static_colors_plus(self, autorun_name);
xrdp_wm_load_static_pointers(self);
self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color;
if (self->session->client_info->rdp_autologin || (autorun_name[0] != 0))
if (self->session->client_info->rdp_autologin)
{
/*
* NOTE: this should eventually be accessed from self->xrdp_config
@ -558,51 +568,52 @@ xrdp_wm_init(struct xrdp_wm *self)
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); /* xrdp.ini */
if (fd > 0)
if (fd != -1)
{
names = list_create();
names->auto_free = 1;
values = list_create();
values->auto_free = 1;
/* domain names that starts with '_' are reserved for IP/DNS to
* simplify for the user in a gateway setup */
if (self->session->client_info->domain[0] != '_')
/* look for module name to be loaded */
if (autorun_name[0] != 0) {
/* if autorun is configured in xrdp.ini, we enforce that module to be loaded */
g_strncpy(section_name, autorun_name, 255);
}
else if (self->session->client_info->domain[0] != '_')
{
/* domain names that starts with '_' are reserved for IP/DNS to
* simplify for the user in a proxy setup */
/* we use the domain name as the module name to be loaded */
g_strncpy(section_name, self->session->client_info->domain,
255);
255);
}
if (section_name[0] == 0)
else
{
if (autorun_name[0] == 0)
/* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
file thats not named
'globals' or 'Logging' or 'channels' */
/* TODO: change this and have a 'autologin'
line in globals section */
file_read_sections(fd, names);
for (index = 0; index < names->count; index++)
{
/* if no domain is passed, and no autorun in xrdp.ini,
use the first item in the xrdp.ini
file thats not named
'globals' or 'Logging' or 'channels' */
/* TODO: change this and have a 'autologin'
line in globals section */
file_read_sections(fd, names);
for (index = 0; index < names->count; index++)
q = (char *)list_get_item(names, index);
if ((g_strncasecmp("globals", q, 8) != 0) &&
(g_strncasecmp("Logging", q, 8) != 0) &&
(g_strncasecmp("channels", q, 9) != 0))
{
q = (char *)list_get_item(names, index);
if ((g_strncasecmp("globals", q, 8) != 0) &&
(g_strncasecmp("Logging", q, 8) != 0) &&
(g_strncasecmp("channels", q, 9) != 0))
{
g_strncpy(section_name, q, 255);
break;
}
g_strncpy(section_name, q, 255);
break;
}
}
else
{
g_strncpy(section_name, autorun_name, 255);
}
}
list_clear(names);
/* look for the required module in xrdp.ini, fetch its parameters */
if (file_read_section(fd, section_name, names, values) == 0)
{
for (index = 0; index < names->count; index++)
@ -632,6 +643,29 @@ xrdp_wm_init(struct xrdp_wm *self)
r = self->session->client_info->username;
}
}
else if (g_strncmp("ip", q, 255) == 0)
{
/* if the ip has been asked for by the module, use what the
client says (target ip should be in 'domain' field, when starting with "_")
if the ip has been manually set in the config, use that
instead of what the client says. */
if (g_strncmp("ask", r, 3) == 0)
{
if (self->session->client_info->domain[0] == '_')
{
g_strncpy(param, &self->session->client_info->domain[1], 255);
r = param;
}
}
}
else if (g_strncmp("port", q, 255) == 0)
{
if (g_strncmp("ask3389", r, 7) == 0)
{
r = "3389"; /* use default */
}
}
list_add_item(self->mm->login_names, (long)g_strdup(q));
list_add_item(self->mm->login_values, (long)g_strdup(r));
@ -639,6 +673,13 @@ xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_set_login_mode(self, 2);
}
else
{
/* requested module name not found in xrdp.ini */
g_writeln(" xrdp_wm_init: file_read_section returned non-zero, requested section not found in xrdp.ini");
xrdp_wm_log_msg(self, "ERROR: The requested xrdp module not found in xrdp.ini,"
" falling back to login window");
}
list_delete(names);
list_delete(values);
@ -651,6 +692,7 @@ xrdp_wm_init(struct xrdp_wm *self)
}
else
{
g_writeln(" xrdp_wm_init: no autologin / auto run detected, draw login window");
xrdp_login_wnd_create(self);
/* clear screen */
xrdp_bitmap_invalidate(self->screen, 0);
@ -658,6 +700,7 @@ xrdp_wm_init(struct xrdp_wm *self)
xrdp_wm_set_login_mode(self, 1);
}
g_writeln("out xrdp_wm_init: ");
return 0;
}
@ -1706,6 +1749,8 @@ xrdp_wm_login_mode_changed(struct xrdp_wm *self)
return 0;
}
g_writeln("xrdp_wm_login_mode_changed: login_mode is %d", self->login_mode);
if (self->login_mode == 0)
{
/* this is the inital state of the login window */
@ -1825,7 +1870,7 @@ void add_string_to_logwindow(char *msg, struct list *log)
/*****************************************************************************/
int APP_CC
xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
xrdp_wm_show_log(struct xrdp_wm *self)
{
struct xrdp_bitmap *but;
int w;
@ -1835,11 +1880,12 @@ xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
if (self->hide_log_window)
{
/* make sure autologin is off */
self->session->client_info->rdp_autologin = 0;
xrdp_wm_set_login_mode(self, 0); /* reset session */
return 0;
}
add_string_to_logwindow(msg, self->log);
if (self->log_wnd == 0)
{
w = DEFAULT_WND_LOG_W;
@ -1886,7 +1932,15 @@ xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
xrdp_wm_set_focused(self, self->log_wnd);
xrdp_bitmap_invalidate(self->log_wnd, 0);
g_sleep(100);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_wm_log_msg(struct xrdp_wm *self, char *msg)
{
add_string_to_logwindow(msg, self->log);
return 0;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

@ -41,7 +41,7 @@ struct wts_obj
{
int fd;
int status;
char name[8];
char name[9];
char dname[128];
int display_num;
uint32_t flags;
@ -124,12 +124,19 @@ WTSVirtualChannelOpenEx(unsigned int SessionId, const char *pVirtualName,
}
/* we use unix domain socket to communicate with chansrv */
wts->fd = socket(AF_UNIX, SOCK_STREAM, 0);
if ((wts->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
g_free(wts);
return NULL;
}
/* set non blocking */
llong = fcntl(wts->fd, F_GETFL);
llong = llong | O_NONBLOCK;
fcntl(wts->fd, F_SETFL, llong);
if (fcntl(wts->fd, F_SETFL, llong) < 0)
{
LLOGLN(10, ("WTSVirtualChannelOpenEx: set non-block mode failed"));
}
/* connect to chansrv session */
memset(&s, 0, sizeof(struct sockaddr_un));
@ -236,11 +243,13 @@ WTSVirtualChannelWrite(void *hChannelHandle, const char *Buffer,
return 0;
}
#if 0 /* coverity: this is dead code */
/* error, but is it ok to try again? */
if ((rv == EWOULDBLOCK) || (rv == EAGAIN) || (rv == EINPROGRESS))
{
return 0; /* failed to send, but should try again */
}
#endif
/* fatal error */
return -1;

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -175,18 +175,14 @@ lib_mod_connect(struct mod *mod)
char con_port[256];
LIB_DEBUG(mod, "in lib_mod_connect");
/* clear screen */
mod->server_begin_update(mod);
mod->server_set_fgcolor(mod, 0);
mod->server_fill_rect(mod, 0, 0, mod->width, mod->height);
mod->server_end_update(mod);
mod->server_msg(mod, "started connecting", 0);
/* only support 8, 15, 16, and 24 bpp connections from rdp client */
if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24)
/* only support 8, 15, 16, 24, and 32 bpp connections from rdp client */
if (mod->bpp != 8 && mod->bpp != 15 && mod->bpp != 16 && mod->bpp != 24 && mod->bpp != 32)
{
mod->server_msg(mod,
"error - only supporting 8, 15, 16, and 24 bpp rdp connections", 0);
"error - only supporting 8, 15, 16, 24, and 32 bpp rdp connections", 0);
LIB_DEBUG(mod, "out lib_mod_connect error");
return 1;
}
@ -207,6 +203,7 @@ lib_mod_connect(struct mod *mod)
use_uds = 1;
}
error = 0;
mod->sck_closed = 0;
i = 0;
@ -215,10 +212,21 @@ lib_mod_connect(struct mod *mod)
if (use_uds)
{
mod->sck = g_tcp_local_socket();
if (mod->sck < 0)
{
free_stream(s);
return 1;
}
}
else
{
mod->sck = g_tcp_socket();
if (mod->sck < 0)
{
free_stream(s);
return 1;
}
g_tcp_set_non_blocking(mod->sck);
g_tcp_set_no_delay(mod->sck);
}
@ -1121,13 +1129,22 @@ process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
in_uint16_le(s, height);
in_sint16_le(s, srcx);
in_sint16_le(s, srcy);
bmpdata = 0;
rv = 0;
if (flags == 0) /* screen */
{
if (mod->screen_shmem_id == 0)
{
mod->screen_shmem_id = shmem_id;
mod->screen_shmem_pixels = g_shmat(mod->screen_shmem_id);
if (mod->screen_shmem_pixels == (void*)-1)
{
/* failed */
mod->screen_shmem_id = 0;
mod->screen_shmem_pixels = 0;
}
}
if (mod->screen_shmem_pixels != 0)
{
@ -1140,10 +1157,6 @@ process_server_paint_rect_shmem(struct mod *mod, struct stream *s)
bmpdata, width, height,
srcx, srcy);
}
else
{
rv = 1;
}
send_paint_rect_ack(mod, flags, x, y, cx, cy, frame_id);
return rv;
}
@ -1248,14 +1261,16 @@ process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
rv = amod->server_paint_rects(amod, num_drects, ldrects,
num_crects, lcrects,
bmpdata, width, height, 0);
bmpdata, width, height,
flags, frame_id);
}
else
{
rv = 1;
}
send_paint_rect_ex_ack(amod, flags, frame_id);
//g_writeln("frame_id %d", frame_id);
//send_paint_rect_ex_ack(amod, flags, frame_id);
g_free(lcrects);
g_free(ldrects);
@ -1379,6 +1394,7 @@ lib_send_client_info(struct mod *mod)
struct stream *s;
int len;
g_writeln("lib_send_client_info:");
make_stream(s);
init_stream(s, 8192);
s_push_layer(s, iso_hdr, 4);
@ -1586,6 +1602,16 @@ lib_mod_check_wait_objs(struct mod *mod)
return rv;
}
/******************************************************************************/
/* return error */
int DEFAULT_CC
lib_mod_frame_ack(struct mod *amod, int flags, int frame_id)
{
LLOGLN(10, ("lib_mod_frame_ack: flags 0x%8.8x frame_id %d", flags, frame_id));
send_paint_rect_ex_ack(amod, flags, frame_id);
return 0;
}
/******************************************************************************/
struct mod *EXPORT_CC
mod_init(void)
@ -1604,6 +1630,7 @@ mod_init(void)
mod->mod_set_param = lib_mod_set_param;
mod->mod_get_wait_objs = lib_mod_get_wait_objs;
mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->mod_frame_ack = lib_mod_frame_ack;
return mod;
}

@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2013
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -44,7 +44,8 @@ struct mod
int (*mod_get_wait_objs)(struct mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct mod* v);
tbus mod_dumby[100 - 9]; /* align, 100 minus the number of mod
int (*mod_frame_ack)(struct mod* v, int flags, int frame_id);
tbus mod_dumby[100 - 10]; /* align, 100 minus the number of mod
functions above */
/* server functions */
int (*server_begin_update)(struct mod* v);
@ -136,7 +137,8 @@ struct mod
int (*server_paint_rects)(struct mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
char *data, int width, int height,
int flags, int frame_id);
tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */

Loading…
Cancel
Save