summaryrefslogtreecommitdiffstats
path: root/sesman/chansrv
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2012-09-08 22:12:22 -0700
committerJay Sorg <jay.sorg@gmail.com>2012-09-08 22:12:22 -0700
commit3399b953ebd331c7d250e2be1e9a92fe4b48f7c3 (patch)
treea0b61b8aa7939775646f2ec459ab5775ccb2aeba /sesman/chansrv
parent38465ae214895dfff10ca25b3e8e7c9f9ee5b1ff (diff)
parent3cedfae76a2351bc8b1e5bd2ee33bbf8630dbacf (diff)
downloadxrdp-proprietary-3399b953ebd331c7d250e2be1e9a92fe4b48f7c3.tar.gz
xrdp-proprietary-3399b953ebd331c7d250e2be1e9a92fe4b48f7c3.zip
Merge branch 'master' of github.com:FreeRDP/xrdp
Diffstat (limited to 'sesman/chansrv')
-rw-r--r--sesman/chansrv/Makefile.am3
-rw-r--r--sesman/chansrv/chansrv.c186
-rw-r--r--sesman/chansrv/chansrv.h14
-rw-r--r--sesman/chansrv/clipboard.c110
-rw-r--r--sesman/chansrv/drdynvc.c17
-rw-r--r--sesman/chansrv/drdynvc.h25
-rw-r--r--sesman/chansrv/xcommon.c2
7 files changed, 266 insertions, 91 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 0beb7f0a..a1b5bed9 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -30,7 +30,8 @@ xrdp_chansrv_SOURCES = \
clipboard.c \
devredir.c \
rail.c \
- xcommon.c
+ xcommon.c \
+ drdynvc.c
xrdp_chansrv_LDFLAGS = \
$(EXTRA_FLAGS)
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index 7c74bb4f..10a42ef9 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -69,59 +69,132 @@ struct xrdp_api_data
};
/*****************************************************************************/
+/* add data to chan_item, on its way to the client */
/* returns error */
-int APP_CC
-send_channel_data(int chan_id, char* data, int size)
+static int APP_CC
+add_data_to_chan_item(struct chan_item* chan_item, char* data, int size)
+{
+ struct stream* s;
+ struct chan_out_data* cod;
+
+ make_stream(s);
+ init_stream(s, size);
+ g_memcpy(s->data, data, size);
+ s->end = s->data + size;
+ cod = (struct chan_out_data*)g_malloc(sizeof(struct chan_out_data), 1);
+ cod->s = s;
+ if (chan_item->tail == 0)
+ {
+ chan_item->tail = cod;
+ chan_item->head = cod;
+ }
+ else
+ {
+ chan_item->tail->next = cod;
+ chan_item->tail = cod;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+send_data_from_chan_item(struct chan_item* chan_item)
{
- struct stream * s;
+ struct stream* s;
+ struct chan_out_data* cod;
+ int bytes_left;
+ int size;
int chan_flags;
- int total_size;
- int sent;
- int rv;
+ int error;
- if (chan_id == -1)
+ if (chan_item->head == 0)
{
- return 1;
+ return 0;
+ }
+ cod = chan_item->head;
+ bytes_left = (int)(cod->s->end - cod->s->p);
+ size = MIN(1600, bytes_left);
+ chan_flags = 0;
+ if (cod->s->p == cod->s->data)
+ {
+ chan_flags |= 1; /* first */
+ }
+ if (cod->s->p + size >= cod->s->end)
+ {
+ chan_flags |= 2; /* last */
}
s = trans_get_out_s(g_con_trans, 8192);
- if (s == 0)
+ out_uint32_le(s, 0); /* version */
+ out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint32_le(s, 8); /* msg id */
+ out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
+ out_uint16_le(s, chan_item->id);
+ out_uint16_le(s, chan_flags);
+ out_uint16_le(s, size);
+ out_uint32_le(s, cod->s->size);
+ out_uint8a(s, cod->s->p, size);
+ s_mark_end(s);
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: -- "
+ "size %d chan_flags 0x%8.8x", size, chan_flags));
+ error = trans_force_write(g_con_trans);
+ if (error != 0)
{
return 1;
}
- rv = 0;
- sent = 0;
- total_size = size;
- while (sent < total_size)
+ cod->s->p += size;
+ if (cod->s->p >= cod->s->end)
{
- size = MIN(1600, total_size - sent);
- chan_flags = 0;
- if (sent == 0)
+ free_stream(cod->s);
+ chan_item->head = chan_item->head->next;
+ if (chan_item->head == 0)
{
- chan_flags |= 1; /* first */
+ chan_item->tail = 0;
}
- if (size + sent == total_size)
+ g_free(cod);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+static int APP_CC
+check_chan_items(void)
+{
+ int index;
+
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].head != 0)
{
- chan_flags |= 2; /* last */
+ send_data_from_chan_item(g_chan_items + index);
}
- out_uint32_le(s, 0); /* version */
- out_uint32_le(s, 8 + 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint32_le(s, 8); /* msg id */
- out_uint32_le(s, 8 + 2 + 2 + 2 + 4 + size); /* size */
- out_uint16_le(s, chan_id);
- out_uint16_le(s, chan_flags);
- out_uint16_le(s, size);
- out_uint32_le(s, total_size);
- out_uint8a(s, data + sent, size);
- s_mark_end(s);
- rv = trans_force_write(g_con_trans);
- if (rv != 0)
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+send_channel_data(int chan_id, char* data, int size)
+{
+ int index;
+
+ LOGM((LOG_LEVEL_DEBUG, "chansrv::send_channel_data: size %d", size));
+ if (chan_id == -1)
+ {
+ return 1;
+ }
+ for (index = 0; index < g_num_chan_items; index++)
+ {
+ if (g_chan_items[index].id == chan_id)
{
- break;
+ add_data_to_chan_item(g_chan_items + index, data, size);
+ check_chan_items();
+ return 0;
}
- sent += size;
- s = trans_get_out_s(g_con_trans, 8192);
}
- return rv;
+ return 1;
}
/*****************************************************************************/
@@ -131,7 +204,7 @@ send_init_response_message(void)
{
struct stream * s = (struct stream *)NULL;
- LOGM((LOG_LEVEL_INFO,"send_init_response_message:"))
+ LOGM((LOG_LEVEL_INFO, "send_init_response_message:"));
s = trans_get_out_s(g_con_trans, 8192);
if (s == 0)
{
@@ -339,6 +412,7 @@ static int APP_CC
process_message_channel_data_response(struct stream* s)
{
LOG(10, ("process_message_channel_data_response:"));
+ check_chan_items();
return 0;
}
@@ -911,21 +985,41 @@ main(int argc, char** argv)
{
tbus waiters[4];
int pid = 0;
- char text[256] = "";
- char* display_text = (char *)NULL;
-#if XRDP_CHANNEL_LOG
- char cfg_file[256];
+ char text[256];
+ char* home_text;
+ char* display_text;
+ char log_file[256];
enum logReturns error;
-#endif
+ struct log_config logconfig;
g_init("xrdp-chansrv"); /* os_calls */
+
+ home_text = g_getenv("HOME");
+ if (home_text == 0)
+ {
+ g_writeln("error reading HOME environment variable");
+ g_deinit();
+ return 1;
+ }
+
read_ini();
pid = g_getpid();
-#if XRDP_CHANNEL_LOG
/* starting logging subsystem */
- g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
- error = log_start(cfg_file,"XRDP-Chansrv");
+ g_memset(&logconfig, 0, sizeof(struct log_config));
+ logconfig.program_name = "XRDP-Chansrv";
+ g_snprintf(log_file, 255, "%s/xrdp-chansrv.log", home_text);
+ g_writeln("chansrv::main: using log file [%s]", log_file);
+ if (g_file_exist(log_file))
+ {
+ g_file_delete(log_file);
+ }
+ logconfig.log_file = log_file;
+ logconfig.fd = -1;
+ logconfig.log_level = LOG_LEVEL_ERROR;
+ logconfig.enable_syslog = 0;
+ logconfig.syslog_level = 0;
+ error = log_start_from_param(&logconfig);
if (error != LOG_STARTUP_OK)
{
switch (error)
@@ -942,10 +1036,9 @@ main(int argc, char** argv)
break;
}
g_deinit();
- g_exit(1);
+ return 1;
}
LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid));
-#endif
/* set up signal handler */
g_signal_kill(term_signal_handler); /* SIGKILL */
g_signal_terminate(term_signal_handler); /* SIGTERM */
@@ -958,6 +1051,7 @@ main(int argc, char** argv)
if (g_display_num == 0)
{
LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
+ g_deinit();
return 1;
}
LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num));
diff --git a/sesman/chansrv/chansrv.h b/sesman/chansrv/chansrv.h
index a7a0f3e7..ba593461 100644
--- a/sesman/chansrv/chansrv.h
+++ b/sesman/chansrv/chansrv.h
@@ -21,14 +21,21 @@
#include "arch.h"
#include "parse.h"
+#include "log.h"
-#define XRDP_CHANNEL_LOG 0
+struct chan_out_data
+{
+ struct stream* s;
+ struct chan_out_data* next;
+};
struct chan_item
{
int id;
int flags;
char name[16];
+ struct chan_out_data* head;
+ struct chan_out_data* tail;
};
int APP_CC
@@ -47,12 +54,7 @@ main_cleanup(void);
} \
}
-#if XRDP_CHANNEL_LOG
-#include "log.h"
#define LOGM(_args) do { log_message _args ; } while (0)
-#else
-#define LOGM(_args)
-#endif
#ifndef GSET_UINT8
#define GSET_UINT8(_ptr, _offset, _data) \
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index abb17e3e..3bea9704 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -95,14 +95,14 @@ static int g_want_image_data = 0;
static XSelectionRequestEvent g_saved_selection_req_event;
/* for clipboard INCR transfers */
-static Atom g_incr_atom;
-static Atom g_incr_atom_type;
-static Atom g_incr_atom_target;
-static char* g_incr_data;
-static int g_incr_data_size;
-static int g_incr_in_progress = 0;
+static Atom g_incr_atom;
+static Atom g_incr_atom_type;
+static Atom g_incr_atom_target;
+static char* g_incr_data = 0;
+static int g_incr_data_size = 0;
+static int g_incr_in_progress = 0;
-static clipboard_format_id = CB_FORMAT_UNICODETEXT;
+static int clipboard_format_id = CB_FORMAT_UNICODETEXT;
/*****************************************************************************/
/* this is one way to get the current time from the x server */
@@ -176,10 +176,10 @@ clipboard_init(void)
}
if (rv == 0)
{
- LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_xfixes_event_base %d",
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d",
g_xfixes_event_base));
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
- LOGM((LOG_LEVEL_ERROR, "clipboard_init st %d, maj %d min %d", st,
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st,
ver_maj, ver_min));
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
False);
@@ -194,6 +194,11 @@ clipboard_init(void)
g_image_bmp_atom = XInternAtom(g_display, "image/bmp", False);
g_incr_atom = XInternAtom(g_display, "INCR", False);
+ if (g_image_bmp_atom == None)
+ {
+ LOGM((LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was "
+ "not allocated"));
+ }
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
0, 0, 4, 4, 0, 0, 0);
@@ -327,10 +332,7 @@ clipboard_send_format_announce(tui32 format_id, char* format_name)
struct stream* s;
int size;
int rv;
- unsigned char format_buf[32];
- g_memset(format_buf, 0, 32);
- g_snprintf(format_buf, 31, "Native");
make_stream(s);
init_stream(s, 8192);
out_uint16_le(s, 2); /* CLIPRDR_FORMAT_ANNOUNCE */
@@ -521,6 +523,9 @@ clipboard_refuse_selection(XSelectionRequestEvent* req)
}
/*****************************************************************************/
+/* sent by client or server when its local system clipboard is
+ updated with new clipboard data; contains Clipboard Format ID
+ and name pairs of new Clipboard Formats on the clipboard. */
static int APP_CC
clipboard_process_format_announce(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -540,6 +545,8 @@ clipboard_process_format_announce(struct stream* s, int clip_msg_status,
}
/*****************************************************************************/
+/* response to CB_FORMAT_LIST; used to indicate whether
+ processing of the Format List PDU was successful */
static int APP_CC
clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -550,6 +557,8 @@ clipboard_prcoess_format_ack(struct stream* s, int clip_msg_status,
}
/*****************************************************************************/
+/* sent by recipient of CB_FORMAT_LIST; used to request data for one
+ of the formats that was listed in CB_FORMAT_LIST */
static int APP_CC
clipboard_process_data_request(struct stream* s, int clip_msg_status,
int clip_msg_len)
@@ -576,7 +585,6 @@ clipboard_process_data_response_for_image(struct stream * s,
char cdata;
int len;
int index;
- int data_in_len;
LOGM((LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: "
"CLIPRDR_DATA_RESPONSE_FOR_IMAGE"));
@@ -600,7 +608,7 @@ clipboard_process_data_response_for_image(struct stream * s,
}
else
{
- return;
+ return 0;
}
while (s_check(s))
{
@@ -783,7 +791,8 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
/*****************************************************************************/
/* this happens when a new app copies something to the clipboard
'CLIPBOARD' Atom
- typedef struct {
+ typedef struct
+ {
int type;
unsigned long serial;
Bool send_event;
@@ -794,7 +803,7 @@ clipboard_data_in(struct stream* s, int chan_id, int chan_flags, int length,
Atom selection;
Time timestamp;
Time selection_timestamp;
-} XFixesSelectionNotifyEvent; */
+ } XFixesSelectionNotifyEvent; */
static int APP_CC
clipboard_event_selection_owner_notify(XEvent* xevent)
{
@@ -836,7 +845,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
XGetWindowProperty(g_display, g_wnd, prop, 0, 0, 0,
AnyPropertyType, &ltype, &lfmt, &ln_items,
&llen_after, &lxdata);
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (ltype == 0)
{
/* XGetWindowProperty failed */
@@ -845,13 +857,14 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
if (ltype == g_incr_atom)
{
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR start"));
g_incr_in_progress = 1;
g_incr_atom_type = prop;
g_incr_data_size = 0;
g_free(g_incr_data);
g_incr_data = 0;
XDeleteProperty(g_display, g_wnd, prop);
- return;
+ return 0;
}
if (llen_after < 1)
@@ -867,20 +880,29 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
if (ltype == 0)
{
/* XGetWindowProperty failed */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 1;
}
lxdata_size = (lfmt / 8) * ln_items;
if (lxdata_size < 1)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 2;
}
if (llen_after > 0)
{
/* should not happen */
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
return 3;
}
if (xdata != 0)
@@ -888,7 +910,10 @@ clipboard_get_window_property(Window wnd, Atom prop, Atom* type, int* fmt,
*xdata = (char*)g_malloc(lxdata_size, 0);
g_memcpy(*xdata, lxdata, lxdata_size);
}
- XFree(lxdata);
+ if (lxdata != 0)
+ {
+ XFree(lxdata);
+ }
if (xdata_size != 0)
{
*xdata_size = lxdata_size;
@@ -937,10 +962,10 @@ clipboard_event_selection_notify(XEvent* xevent)
int convert_to_bmp_image;
int send_format_announce;
int atom;
- int* atoms;
+ Atom* atoms;
Atom type;
tui32 format_id;
- unsigned char format_name[32];
+ char format_name[32];
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:"));
data_size = 0;
@@ -948,7 +973,9 @@ clipboard_event_selection_notify(XEvent* xevent)
fmt = 0;
convert_to_string = 0;
convert_to_utf8 = 0;
+ convert_to_bmp_image = 0;
send_format_announce = 0;
+ format_id = 0;
rv = 0;
data = 0;
type = 0;
@@ -985,9 +1012,10 @@ clipboard_event_selection_notify(XEvent* xevent)
{
if (lxevent->target == g_targets_atom)
{
+ /* on a 64 bit machine, actual_format_return of 32 implies long */
if ((type == XA_ATOM) && (fmt == 32))
{
- atoms = (int*)data;
+ atoms = (Atom*)data;
for (index = 0; index < n_items; index++)
{
atom = atoms[index];
@@ -1026,6 +1054,7 @@ clipboard_event_selection_notify(XEvent* xevent)
g_memcpy(g_last_clip_data, data, g_last_clip_size);
g_last_clip_data[g_last_clip_size] = 0;
send_format_announce = 1;
+ format_id = CB_FORMAT_UNICODETEXT;
}
else if (lxevent->target == XA_STRING)
{
@@ -1124,7 +1153,6 @@ clipboard_event_selection_request(XEvent* xevent)
int n_items;
int xdata_size;
char* xdata;
- int i;
lxev = (XSelectionRequestEvent*)xevent;
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %d, "
@@ -1163,7 +1191,6 @@ clipboard_event_selection_request(XEvent* xevent)
/* target, property pairs */
LOGM((LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
"g_multiple_atom"));
-#if 0
if (clipboard_get_window_property(xev.xselection.requestor,
xev.xselection.property,
&type, &fmt, &n_items, &xdata,
@@ -1174,7 +1201,6 @@ clipboard_event_selection_request(XEvent* xevent)
/* todo */
g_free(xdata);
}
-#endif
}
else if ((lxev->target == XA_STRING) || (lxev->target == g_utf8_atom))
{
@@ -1205,6 +1231,18 @@ clipboard_event_selection_request(XEvent* xevent)
return 0;
}
}
+ else if (lxev->target == g_image_bmp_atom)
+ {
+ g_memcpy(&g_saved_selection_req_event, lxev,
+ sizeof(g_saved_selection_req_event));
+ g_last_clip_type = g_image_bmp_atom;
+ g_want_image_data = 1;
+ clipboard_format_id = CB_FORMAT_DIB;
+ clipboard_send_data_request();
+ g_waiting_for_data_response = 1;
+ g_waiting_for_data_response_time = clipboard_get_local_time();
+ return 0;
+ }
else
{
LOGM((LOG_LEVEL_ERROR,"clipboard_event_selection_request: unknown "
@@ -1257,7 +1295,7 @@ clipboard_event_property_notify(XEvent* xevent)
int format_in_bytes;
int new_data_len;
char* cptr;
- unsigned char format_name[32];
+ char format_name[32];
LOG(10, ("clipboard_check_wait_objs: PropertyNotify .window %d "
".state %d .atom %d", xevent->xproperty.window,
@@ -1276,11 +1314,13 @@ clipboard_event_property_notify(XEvent* xevent)
}
if (bytes_left <= 0)
{
+ LOGM((LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"));
g_memset(format_name, 0, 32);
/* clipboard INCR cycle has completed */
g_incr_in_progress = 0;
g_last_clip_size = g_incr_data_size;
g_last_clip_data = g_incr_data;
+ g_incr_data = 0;
g_last_clip_type = g_incr_atom_target;
if (g_incr_atom_target == g_image_bmp_atom)
{
@@ -1296,25 +1336,22 @@ clipboard_event_property_notify(XEvent* xevent)
&nitems_returned, &bytes_left, (unsigned char **) &data);
format_in_bytes = actual_format_return / 8;
- if (actual_format_return == 32 && sizeof(long) == 8)
+ if ((actual_format_return == 32) && (sizeof(long) == 8))
{
/* on a 64 bit machine, actual_format_return of 32 implies long */
format_in_bytes = 8;
}
new_data_len = nitems_returned * format_in_bytes;
-#if 1
+ cptr = (char*)g_malloc(g_incr_data_size + new_data_len, 0);
+ g_memcpy(cptr, g_incr_data, g_incr_data_size);
g_free(g_incr_data);
- cptr = (char *) g_malloc(g_incr_data_size + new_data_len, 0);
-#else
- cptr = (char *) realloc(g_incr_data, g_incr_data_size + new_data_len);
-#endif
if (cptr == NULL)
{
+ g_incr_data = 0;
/* cannot add any more data */
if (data != 0)
{
XFree(data);
- data = 0;
}
XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
return 0;
@@ -1325,7 +1362,6 @@ clipboard_event_property_notify(XEvent* xevent)
if (data)
{
XFree(data);
- data = 0;
}
XDeleteProperty(g_display, g_wnd, g_incr_atom_type);
}
diff --git a/sesman/chansrv/drdynvc.c b/sesman/chansrv/drdynvc.c
new file mode 100644
index 00000000..da0e8fe3
--- /dev/null
+++ b/sesman/chansrv/drdynvc.c
@@ -0,0 +1,17 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
diff --git a/sesman/chansrv/drdynvc.h b/sesman/chansrv/drdynvc.h
new file mode 100644
index 00000000..14237835
--- /dev/null
+++ b/sesman/chansrv/drdynvc.h
@@ -0,0 +1,25 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ *
+ * 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.
+ */
+
+#if !defined(DRDYNVC_H)
+#define DRDYNVC_H
+
+#include "arch.h"
+#include "parse.h"
+
+#endif
diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c
index 5510a055..70b52694 100644
--- a/sesman/chansrv/xcommon.c
+++ b/sesman/chansrv/xcommon.c
@@ -164,7 +164,7 @@ xcommon_check_wait_objs(void)
{
time_diff = xcommon_get_local_time() -
g_waiting_for_data_response_time;
- if (time_diff > 1000)
+ if (time_diff > 10000)
{
LOGM((LOG_LEVEL_ERROR, "xcommon_check_wait_objs: warning, "
"waiting for data response too long"));