diff options
Diffstat (limited to 'xrdp/xrdp_mm.c')
-rw-r--r-- | xrdp/xrdp_mm.c | 685 |
1 files changed, 652 insertions, 33 deletions
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 4001677f..66f3b1d9 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -21,6 +21,8 @@ */ #include "xrdp.h" +#include "log.h" +#define ACCESS #include "libraptorsmiface.h" @@ -65,6 +67,7 @@ xrdp_mm_sync_load(long param1, long param2) static void APP_CC xrdp_mm_module_cleanup(struct xrdp_mm* self) { + g_writeln("xrdp_mm_module_cleanup"); if (self->mod != 0) { if (self->mod_exit != 0) @@ -75,7 +78,7 @@ xrdp_mm_module_cleanup(struct xrdp_mm* self) } if (self->mod_handle != 0) { - /* main thread unload */ + /* Let the main thread unload the module.*/ g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0); } trans_delete(self->chan_trans); @@ -106,6 +109,7 @@ xrdp_mm_delete(struct xrdp_mm* self) } /*****************************************************************************/ +/* Send login information to sesman */ static int APP_CC xrdp_mm_send_login(struct xrdp_mm* self) { @@ -204,6 +208,7 @@ xrdp_mm_send_login(struct xrdp_mm* self) s_mark_end(s); s_pop_layer(s, channel_hdr); + /* Version 0 of the protocol to sesman is currently used by XRDP */ out_uint32_be(s, 0); /* version */ index = (int)(s->end - s->data); out_uint32_be(s, index); /* size */ @@ -284,6 +289,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) } if (self->mod_handle == 0) { + /* Let the main thread load the lib,*/ self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0); if (self->mod_handle != 0) { @@ -319,6 +325,8 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) g_writeln("loaded module '%s' ok, interface size %d, version %d", lib, self->mod->size, self->mod->version); } + }else{ + g_writeln("no mod_init or mod_exit address found"); } } else @@ -326,6 +334,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please " "add a valid entry like lib=libxrdp-vnc.so or similar", lib); xrdp_wm_log_msg(self->wm, text); + return 1; } if (self->mod != 0) { @@ -355,6 +364,18 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) self->mod->server_query_channel = server_query_channel; self->mod->server_get_channel_id = server_get_channel_id; self->mod->server_send_to_channel = server_send_to_channel; + self->mod->server_create_os_surface = server_create_os_surface; + self->mod->server_switch_os_surface = server_switch_os_surface; + self->mod->server_delete_os_surface = server_delete_os_surface; + self->mod->server_paint_rect_os = server_paint_rect_os; + self->mod->server_set_hints = server_set_hints; + self->mod->server_window_new_update = server_window_new_update; + self->mod->server_window_delete = server_window_delete; + self->mod->server_window_icon = server_window_icon; + self->mod->server_window_cached_icon = server_window_cached_icon; + self->mod->server_notify_new_update = server_notify_new_update; + self->mod->server_notify_delete = server_notify_delete; + self->mod->server_monitored_desktop = server_monitored_desktop; } } /* id self->mod is null, there must be a problem */ @@ -778,6 +799,17 @@ xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port) return 0; } +static void cleanup_sesman_connection(struct xrdp_mm* self) +{ + self->delete_sesman_trans = 1; + self->connected_state = 0; + if (self->wm->login_mode != 10) + { + xrdp_wm_set_login_mode(self->wm, 11); + xrdp_mm_module_cleanup(self); + } +} + /*****************************************************************************/ static int APP_CC xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s) @@ -785,8 +817,6 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s) int ok; int display; int rv; - int uid; - int gid; char text[256]; char ip[256]; char port[256]; @@ -828,14 +858,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s) xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: " "login failed"); } - self->delete_sesman_trans = 1; - self->connected_state = 0; - if (self->wm->login_mode != 10) - { - xrdp_wm_set_login_mode(self->wm, 11); - xrdp_mm_module_cleanup(self); - } - + cleanup_sesman_connection(self); return rv; } @@ -940,6 +963,7 @@ xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2, } /*****************************************************************************/ +/* This is the callback registered for sesman communication replies. */ static int APP_CC xrdp_mm_sesman_data_in(struct trans* trans) { @@ -968,11 +992,14 @@ xrdp_mm_sesman_data_in(struct trans* trans) in_uint16_be(s, code); switch (code) { + /* even when the request is denied the reply will hold 3 as the command. */ case 3: error = xrdp_mm_process_login_response(self, s); break; default: - g_writeln("xrdp_mm_sesman_data_in: unknown code %d", code); + xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman"); + g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code); + cleanup_sesman_connection(self); break; } } @@ -980,6 +1007,133 @@ xrdp_mm_sesman_data_in(struct trans* trans) return error; } +#ifdef ACCESS +/*********************************************************************/ +/* return 0 on success */ +int access_control(char *username, char *password, char *srv) +{ + int reply; + int rec = 1; // failure + struct stream* in_s; + struct stream* out_s; + unsigned long version; + unsigned short int dummy; + unsigned short int ok; + unsigned short int code; + unsigned long size; + int index; + int socket = g_tcp_socket(); + if (socket > 0) + { + /* we use a blocking socket here */ + reply = g_tcp_connect(socket, srv, "3350"); + if (reply == 0) + { + make_stream(in_s); + init_stream(in_s, 500); + make_stream(out_s); + init_stream(out_s, 500); + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/ + index = g_strlen(username); + out_uint16_be(out_s, index); + out_uint8a(out_s, username, index); + + index = g_strlen(password); + out_uint16_be(out_s, index); + out_uint8a(out_s, password, index); + s_mark_end(out_s); + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + index = (int)(out_s->end - out_s->data); + out_uint32_be(out_s, index); /* size */ + /* g_writeln("Number of data to send : %d",index); */ + reply = g_tcp_send(socket, out_s->data, index, 0); + free_stream(out_s); + if (reply > 0) + { + /* We wait in 5 sec for a reply from sesman*/ + if (g_tcp_can_recv(socket, 5000)) + { + reply = g_tcp_recv(socket, in_s->end, 500, 0); + if (reply > 0) + { + in_s->end = in_s->end + reply; + in_uint32_be(in_s, version); + /*g_writeln("Version number in reply from sesman: %d",version) ; */ + in_uint32_be(in_s, size); + if ((size == 14) && (version == 0)) + { + in_uint16_be(in_s, code); + in_uint16_be(in_s, ok); + in_uint16_be(in_s, dummy); + if (code != 4) + { + log_message(LOG_LEVEL_ERROR, "Returned cmd code from " + "sesman is corrupt"); + } + else + { + rec = ok; /* here we read the reply from the access control */ + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Corrupt reply size or " + "version from sesman: %d", size); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "No data received from sesman"); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman"); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "No success sending to sesman"); + } + free_stream(in_s); + g_tcp_close(socket); + } + else + { + log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman"); + } + } + else + { + log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control"); + } + return rec; +} +#endif + +/*****************************************************************************/ +/* This routine clears all states to make sure that our next login will be + * as expected. If the user does not press ok on the log window and try to + * connect again we must make sure that no previous information is stored.*/ +void cleanup_states(struct xrdp_mm* self) +{ + if (self != NULL) + { + self-> connected_state = 0; /* true if connected to sesman else false */ + self-> sesman_trans = NULL; /* connection to sesman */ + 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-> 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 */ + self-> delete_chan_trans = 0; /* boolean set when done with channel connection */ + self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */ + } +} /*****************************************************************************/ int APP_CC xrdp_mm_connect(struct xrdp_mm* self) @@ -988,7 +1142,6 @@ xrdp_mm_connect(struct xrdp_mm* self) struct list* values; int index; int count; - int use_sesman; int ok; int rv; char* name; @@ -998,14 +1151,24 @@ xrdp_mm_connect(struct xrdp_mm* self) char text[256]; char port[8]; char chansrvport[256]; - +#ifdef ACCESS + int use_pam_auth = 0; + char pam_auth_sessionIP[256]; + char pam_auth_password[256]; + char pam_auth_username[256]; + char username[256]; + char password[256]; + username[0] = 0; + password[0] = 0; +#endif + /* make sure we start in correct state */ + cleanup_states(self); g_memset(ip, 0, sizeof(ip)); g_memset(errstr, 0, sizeof(errstr)); g_memset(text, 0, sizeof(text)); g_memset(port, 0, sizeof(port)); g_memset(chansrvport, 0, sizeof(chansrvport)); rv = 0; /* success */ - use_sesman = 0; names = self->login_names; values = self->login_values; count = names->count; @@ -1021,25 +1184,84 @@ xrdp_mm_connect(struct xrdp_mm* self) { if (g_strcasecmp(value, "-1") == 0) { - use_sesman = 1; + self->sesman_controlled = 1; } } +#ifdef ACCESS + else if (g_strcasecmp(name, "pamusername") == 0) + { + use_pam_auth = 1; + g_strncpy(pam_auth_username, value, 255); + } + else if (g_strcasecmp(name, "pamsessionmng") == 0) + { + g_strncpy(pam_auth_sessionIP, value, 255); + } + else if (g_strcasecmp(name, "pampassword") == 0) + { + g_strncpy(pam_auth_password, value, 255); + } + else if (g_strcasecmp(name, "password") == 0) + { + g_strncpy(password, value, 255); + } + else if (g_strcasecmp(name, "username") == 0) + { + g_strncpy(username, value, 255); + } +#endif else if (g_strcasecmp(name, "chansrvport") == 0) { g_strncpy(chansrvport, value, 255); self->usechansrv = 1; } } - if (use_sesman) +#ifdef ACCESS + if (use_pam_auth) + { + int reply; + char replytxt[80]; + char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"}; + xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control..."); + /* g_writeln("we use pam modules to check if we can approve this user"); */ + if (!g_strncmp(pam_auth_username, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username); + g_strncpy(pam_auth_username,username, 255); + } + if (!g_strncmp(pam_auth_password, "same", 255)) + { + log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password); + g_strncpy(pam_auth_password, password, 255); + } + /* access_control return 0 on success */ + reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); + if (reply >= 0 && reply < 4) + { + g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]); + } + else + { + g_sprintf(replytxt,"Reply from access control undefined"); + } + xrdp_wm_log_msg(self->wm,replytxt); + log_message(LOG_LEVEL_INFO,replytxt); + if (reply != 0) + { + rv = 1; + return rv; + } + } +#endif + if (self->sesman_controlled) { ok = 0; - errstr[0] = 0; trans_delete(self->sesman_trans); self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192); xrdp_mm_get_sesman_port(port, sizeof(port)); g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port); xrdp_wm_log_msg(self->wm, text); - + /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */ self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in; self->sesman_trans->header_size = 8; self->sesman_trans->callback_data = self; @@ -1065,6 +1287,8 @@ xrdp_mm_connect(struct xrdp_mm* self) } else { + g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s", + ip, port); xrdp_wm_log_msg(self->wm, errstr); trans_delete(self->sesman_trans); self->sesman_trans = 0; @@ -1079,23 +1303,27 @@ xrdp_mm_connect(struct xrdp_mm* self) if (xrdp_mm_setup_mod2(self) == 0) { xrdp_wm_set_login_mode(self->wm, 10); + rv = 0; /*sucess*/ } else { /* connect error */ - g_snprintf(errstr, 255, "Failure to connect to: %s port: %s", - ip, port); + g_snprintf(errstr, 255, "Failure to connect to: %s", ip); xrdp_wm_log_msg(self->wm, errstr); - rv = 1 ; /* failure */ + rv = 1; /* failure */ } } + else + { + g_writeln("Failure setting up module"); + } if (self->wm->login_mode != 10) { xrdp_wm_set_login_mode(self->wm, 11); xrdp_mm_module_cleanup(self); + rv = 1; /* failure */ } } - self->sesman_controlled = use_sesman; if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) && (self->usechansrv != 0)) @@ -1103,6 +1331,7 @@ xrdp_mm_connect(struct xrdp_mm* self) /* if sesman controlled, this will connect later */ xrdp_mm_connect_chansrv(self, "", chansrvport); } + g_writeln("returnvalue from xrdp_mm_connect %d", rv); return rv; } @@ -1122,11 +1351,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self, rv = 0; if ((self->sesman_trans != 0) && self->sesman_trans_up) { - trans_get_wait_objs(self->sesman_trans, read_objs, rcount, timeout); + trans_get_wait_objs(self->sesman_trans, read_objs, rcount); } if ((self->chan_trans != 0) && self->chan_trans_up) { - trans_get_wait_objs(self->chan_trans, read_objs, rcount, timeout); + trans_get_wait_objs(self->chan_trans, read_objs, rcount); } if (self->mod != 0) { @@ -1266,7 +1495,7 @@ server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy) return 0; } wm = (struct xrdp_wm*)(mod->wm); - xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy); + xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy); return 0; } @@ -1285,7 +1514,7 @@ server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy, } wm = (struct xrdp_wm*)(mod->wm); p->rop = 0xcc; - xrdp_painter_copy(p, wm->screen, wm->screen, x, y, cx, cy, srcx, srcy); + xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy); return 0; } @@ -1305,7 +1534,7 @@ server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy, } wm = (struct xrdp_wm*)(mod->wm); b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm); - xrdp_painter_copy(p, b, wm->screen, x, y, cx, cy, srcx, srcy); + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); xrdp_bitmap_delete(b); return 0; } @@ -1496,7 +1725,7 @@ server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2) return 0; } wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_line(p, wm->screen, x1, y1, x2, y2); + return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2); } /*****************************************************************************/ @@ -1535,7 +1764,7 @@ server_draw_text(struct xrdp_mod* mod, int font, return 0; } wm = (struct xrdp_wm*)(mod->wm); - return xrdp_painter_draw_text2(p, wm->screen, font, flags, + return xrdp_painter_draw_text2(p, wm->target_surface, font, flags, mixmode, clip_left, clip_top, clip_right, clip_bottom, box_left, box_top, @@ -1581,8 +1810,164 @@ server_reset(struct xrdp_mod* mod, int width, int height, int bpp) xrdp_wm_load_static_pointers(wm); return 0; } +/* read the channel section of the ini file into lists + * return 1 on success 0 on failure */ +int read_allowed_channel_names(struct list* names, struct list* values) +{ + int fd; + 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) + { + names->auto_free = 1; + values->auto_free = 1; + pos = 0; + /* all values in this section can be valid channel names */ + if (file_read_section(fd, "channels", names, values) == 0) + { + ret = 1; + } + else + { + g_writeln("Failure reading channel section of configuration"); + } + g_file_close(fd); + return ret; + } +} +/* internal function return 1 if name is in list of channels + * and if the value is allowed */ +int DEFAULT_CC +is_name_in_lists(char* inName, struct list* names, struct list* values) +{ + int reply = 0; /*means not in the list*/ + int index; + char* val; + char* name; + for (index = 0; index < names->count; index++) + { + name = (char*)list_get_item(names, index); + if (name != 0) + { + /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */ + if (!g_strncmp(name, inName, MAX_CHANNEL_NAME)) + { + val = (char*)list_get_item(values, index); + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + reply = 1; + } + else + { + g_writeln("This channel is disabled: %s", name); + } + break; /* stop loop - item found*/ + } + } + } + return reply; +} +/* internal function only used once per session + * creates the list of allowed channels and store the information + * in wm struct */ +void init_channel_allowed(struct xrdp_wm* wm) +{ + int error; + int i; + char channelname[MAX_CHANNEL_NAME]; + int index = 0; + int allowindex = 0; + struct list* names; + struct list* values; + /* first reset allowedchannels */ + for (i = 0; i < MAX_NR_CHANNELS; i++) + { + /* 0 is a valid channel so we use -1 to mark the index as unused */ + wm->allowedchannels[i] = -1; + } + names = list_create(); + values = list_create(); + if (read_allowed_channel_names(names, values)) + { + do + { + /* libxrdp_query_channel return 1 on error*/ + error = libxrdp_query_channel(wm->session, index, channelname,NULL); + if (error == 0) + { + /* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */ + if (is_name_in_lists(channelname, names, values)) + { + g_writeln("The following channel is allowed: %s", channelname); + wm->allowedchannels[allowindex] = index; + allowindex++; + if (allowindex >= MAX_NR_CHANNELS) + { + g_writeln("Programming error in is_channel_allowed"); + error = 1; /* end loop */ + } + } + else + { + g_writeln("The following channel is not allowed: %s",channelname); + } + index++; + } + } while ((error == 0) && (index < MAX_NR_CHANNELS)); + } + else + { + g_writeln("Error reading channel section in inifile"); + } + list_delete(names); + list_delete(values); +} + +/*****************************************************************************/ +/* This function returns 1 if the channelID is allowed by rule set + * returns 0 if not allowed */ +int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id) +{ + int i; + int reply = 0; /* not allowed */ + /* The first time each client is using this function we have to + * define the list of allowed channels */ + if (wm->allowedinitialized == 0) + { + init_channel_allowed(wm); + g_writeln("allow channel list initialized"); + wm->allowedinitialized = 1; + } + for(i = 0; i < MAX_NR_CHANNELS; i++) + { + if (channel_id == wm->allowedchannels[i]) + { + /*g_writeln("Channel allowed: %d",channel_id);*/ + reply = 1; /*channel allowed*/ + break; + } + else if (wm->allowedchannels[i] == -1) + { + /* We are in the unused space of the allowedchannels list + * We can end the loop */ + break; + } + } + /*if (reply == 0) + { + g_writeln("This channel is NOT allowed: %d",channel_id) ; + }*/ + return reply; +} /*****************************************************************************/ +/*return 0 if the index is not found*/ int DEFAULT_CC server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, int* channel_flags) @@ -1622,10 +2007,244 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id, struct xrdp_wm* wm; wm = (struct xrdp_wm*)(mod->wm); - if (wm->mm->usechansrv) + if (is_channel_allowed(wm, channel_id)) + { + if (wm->mm->usechansrv) + { + return 1; + } + return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, + total_data_len, flags); + } + else + { + return 1; + } +} + +/*****************************************************************************/ +int DEFAULT_CC +server_create_os_surface(struct xrdp_mod* mod, int rdpindex, + int width, int height) +{ + struct xrdp_wm* wm; + struct xrdp_bitmap* bitmap; + int error; + + wm = (struct xrdp_wm*)(mod->wm); + bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp, + WND_TYPE_OFFSCREEN, wm); + error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex); + if (error != 0) { + g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed"); return 1; } - return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, - total_data_len, flags); + bitmap->item_index = rdpindex; + bitmap->id = rdpindex; + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_switch_os_surface(struct xrdp_mod* mod, int rdpindex) +{ + struct xrdp_wm* wm; + struct xrdp_os_bitmap_item* bi; + struct xrdp_painter* p; + + //g_writeln("server_switch_os_surface: id 0x%x", id); + wm = (struct xrdp_wm*)(mod->wm); + if (rdpindex == -1) + { + //g_writeln("server_switch_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + p = (struct xrdp_painter*)(mod->painter); + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + return 0; + } + bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); + if (bi != 0) + { + //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id); + wm->target_surface = bi->bitmap; + p = (struct xrdp_painter*)(mod->painter); + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + } + else + { + g_writeln("server_switch_os_surface: error finding id %d", rdpindex); + } + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_delete_os_surface(struct xrdp_mod* mod, int rdpindex) +{ + struct xrdp_wm* wm; + struct xrdp_painter* p; + + //g_writeln("server_delete_os_surface: id 0x%x", id); + wm = (struct xrdp_wm*)(mod->wm); + if (wm->target_surface->type == WND_TYPE_OFFSCREEN) + { + if (wm->target_surface->id == rdpindex) + { + g_writeln("server_delete_os_surface: setting target_surface to screen"); + wm->target_surface = wm->screen; + p = (struct xrdp_painter*)(mod->painter); + if (p != 0) + { + //g_writeln("setting target"); + wm_painter_set_target(p); + } + } + } + xrdp_cache_remove_os_bitmap(wm->cache, rdpindex); + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy, + int rdpindex, int srcx, int srcy) +{ + struct xrdp_wm* wm; + struct xrdp_bitmap* b; + struct xrdp_painter* p; + struct xrdp_os_bitmap_item* bi; + + p = (struct xrdp_painter*)(mod->painter); + if (p == 0) + { + return 0; + } + wm = (struct xrdp_wm*)(mod->wm); + bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex); + if (bi != 0) + { + b = bi->bitmap; + xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy); + } + else + { + g_writeln("server_paint_rect_os: error finding id %d", rdpindex); + } + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_set_hints(struct xrdp_mod* mod, int hints, int mask) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + if (mask & 1) + { + if (hints & 1) + { + wm->hints |= 1; + } + else + { + wm->hints &= ~1; + } + } + return 0; +} + +/*****************************************************************************/ +int DEFAULT_CC +server_window_new_update(struct xrdp_mod* mod, int window_id, + struct rail_window_state_order* window_state, + int flags) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_window_new_update(wm->session, window_id, + window_state, flags); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_window_delete(struct xrdp_mod* mod, int window_id) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_window_delete(wm->session, window_id); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry, + int cache_id, struct rail_icon_info* icon_info, + int flags) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id, + icon_info, flags); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_window_cached_icon(struct xrdp_mod* mod, + int window_id, int cache_entry, + int cache_id, int flags) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_window_cached_icon(wm->session, window_id, cache_entry, + cache_id, flags); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_notify_new_update(struct xrdp_mod* mod, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_notify_new_update(wm->session, window_id, notify_id, + notify_state, flags); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_notify_delete(struct xrdp_mod* mod, int window_id, + int notify_id) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_notify_delete(wm->session, window_id, notify_id); +} + +/*****************************************************************************/ +int DEFAULT_CC +server_monitored_desktop(struct xrdp_mod* mod, + struct rail_monitored_desktop_order* mdo, + int flags) +{ + struct xrdp_wm* wm; + + wm = (struct xrdp_wm*)(mod->wm); + return libxrdp_monitored_desktop(wm->session, mdo, flags); } |