rail: proxy rail

ulab-next
Jay Sorg 12 years ago
parent 7dc5a77116
commit dc6be76b11

@ -0,0 +1,147 @@
/**
* 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(_RAIL_H)
#define _RAIL_H
/*
ORDER_TYPE_WINDOW
WINDOW_ORDER_TYPE_WINDOW
WINDOW_ORDER_ICON
WINDOW_ORDER_CACHED_ICON
WINDOW_ORDER_STATE_DELETED
WINDOW_ORDER_STATE_NEW on
WINDOW_ORDER_STATE_NEW off
WINDOW_ORDER_TYPE_NOTIFY
WINDOW_ORDER_STATE_DELETED
WINDOW_ORDER_STATE_NEW on
WINDOW_ORDER_STATE_NEW off
WINDOW_ORDER_TYPE_DESKTOP
WINDOW_ORDER_FIELD_DESKTOP_NONE on
WINDOW_ORDER_FIELD_DESKTOP_NONE off
*/
/* Window Order Header Flags */
#define WINDOW_ORDER_TYPE_WINDOW 0x01000000
#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000
#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000
#define WINDOW_ORDER_STATE_NEW 0x10000000
#define WINDOW_ORDER_STATE_DELETED 0x20000000
#define WINDOW_ORDER_FIELD_OWNER 0x00000002
#define WINDOW_ORDER_FIELD_STYLE 0x00000008
#define WINDOW_ORDER_FIELD_SHOW 0x00000010
#define WINDOW_ORDER_FIELD_TITLE 0x00000004
#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000
#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000
#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000
#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000
#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800
#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000
#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400
#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100
#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000
#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200
#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000
#define WINDOW_ORDER_ICON 0x40000000
#define WINDOW_ORDER_CACHED_ICON 0x80000000
#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008
#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001
#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002
#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004
#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001
#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002
#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004
#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008
#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010
#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020
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;
};
struct rail_window_rect
{
short left;
short top;
short right;
short bottom;
};
struct rail_notify_icon_infotip
{
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;
};
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;
};
struct rail_monitored_desktop_order
{
int active_window_id;
int num_window_ids;
int* window_ids;
};
#endif

@ -19,6 +19,7 @@
#include "xrdp-freerdp.h" #include "xrdp-freerdp.h"
#include "xrdp-color.h" #include "xrdp-color.h"
#include "xrdp_rail.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOG(_level, _args) \ #define LLOG(_level, _args) \
@ -228,8 +229,8 @@ lxrdp_event(struct mod* mod, int msg, long param1, long param2,
*/ */
rectangle->left = (param1 >> 16) & 0xffff; rectangle->left = (param1 >> 16) & 0xffff;
rectangle->top = param1 & 0xffff; rectangle->top = param1 & 0xffff;
rectangle->right = (param2 >> 16) & 0xffff + rectangle->left - 1; rectangle->right = (((param2 >> 16) & 0xffff) + rectangle->left) - 1;
rectangle->bottom = param2 & 0xffff + rectangle->top - 1; rectangle->bottom = ((param2 & 0xffff) + rectangle->top) - 1;
if (mod->inst->settings->refresh_rect) if (mod->inst->settings->refresh_rect)
{ {
if (mod->inst->update != NULL) if (mod->inst->update != NULL)
@ -279,13 +280,14 @@ lxrdp_event(struct mod* mod, int msg, long param1, long param2,
switch (flags & 3) switch (flags & 3)
{ {
case 3: case 3:
mod->inst->SendChannelData(mod->inst, lchid, data, total_size); mod->inst->SendChannelData(mod->inst, lchid, (tui8*)data, total_size);
break; break;
case 2: case 2:
/* end */ /* end */
g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size); g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
mod->chan_buf_valid += size; mod->chan_buf_valid += size;
mod->inst->SendChannelData(mod->inst, lchid, mod->chan_buf, total_size); mod->inst->SendChannelData(mod->inst, lchid, (tui8*)(mod->chan_buf),
total_size);
g_free(mod->chan_buf); g_free(mod->chan_buf);
mod->chan_buf = 0; mod->chan_buf = 0;
mod->chan_buf_bytes = 0; mod->chan_buf_bytes = 0;
@ -391,6 +393,7 @@ lxrdp_set_param(struct mod* mod, char* name, char* value)
} }
else if (g_strcmp(name, "client_info") == 0) else if (g_strcmp(name, "client_info") == 0)
{ {
g_memcpy(&(mod->client_info), value, sizeof(mod->client_info));
/* This is a Struct and cannot be printed in next else*/ /* This is a Struct and cannot be printed in next else*/
LLOGLN(10, ("Client_info struct ignored")); LLOGLN(10, ("Client_info struct ignored"));
} }
@ -509,10 +512,10 @@ lfreerdp_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
int j; int j;
int line_bytes; int line_bytes;
BITMAP_DATA* bd; BITMAP_DATA* bd;
tui8* dst_data; char* dst_data;
tui8* dst_data1; char* dst_data1;
tui8* src; char* src;
tui8* dst; char* dst;
mod = ((struct mod_context*)context)->modi; mod = ((struct mod_context*)context)->modi;
LLOGLN(10, ("lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count)); LLOGLN(10, ("lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count));
@ -527,15 +530,15 @@ lfreerdp_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmap)
cx = (bd->destRight - bd->destLeft) + 1; cx = (bd->destRight - bd->destLeft) + 1;
cy = (bd->destBottom - bd->destTop) + 1; cy = (bd->destBottom - bd->destTop) + 1;
line_bytes = server_Bpp * bd->width; line_bytes = server_Bpp * bd->width;
dst_data = (tui8*)g_malloc(bd->height * line_bytes + 16, 0); dst_data = (char*)g_malloc(bd->height * line_bytes + 16, 0);
if (bd->compressed) if (bd->compressed)
{ {
bitmap_decompress(bd->bitmapDataStream, dst_data, bd->width, bitmap_decompress(bd->bitmapDataStream, (tui8*)dst_data, bd->width,
bd->height, bd->bitmapLength, server_bpp, server_bpp); bd->height, bd->bitmapLength, server_bpp, server_bpp);
} }
else else
{ /* bitmap is upside down */ { /* bitmap is upside down */
src = bd->bitmapDataStream; src = (char*)(bd->bitmapDataStream);
dst = dst_data + bd->height * line_bytes; dst = dst_data + bd->height * line_bytes;
for (j = 0; j < bd->height; j++) for (j = 0; j < bd->height; j++)
{ {
@ -614,7 +617,8 @@ lfreerdp_pat_blt(rdpContext* context, PATBLT_ORDER* patblt)
else else
{ {
mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y, mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
patblt->brush.style, patblt->brush.p8x8); patblt->brush.style,
(char*)(patblt->brush.p8x8));
} }
mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect, mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect,
patblt->nWidth, patblt->nHeight); patblt->nWidth, patblt->nHeight);
@ -728,7 +732,7 @@ lfreerdp_glyph_index(rdpContext* context, GLYPH_INDEX_ORDER* glyph_index)
glyph_index->opLeft, glyph_index->opTop, glyph_index->opLeft, glyph_index->opTop,
glyph_index->opRight, glyph_index->opBottom, glyph_index->opRight, glyph_index->opBottom,
glyph_index->x, glyph_index->y, glyph_index->x, glyph_index->y,
glyph_index->data, glyph_index->cbData); (char*)(glyph_index->data), glyph_index->cbData);
} }
/******************************************************************************/ /******************************************************************************/
@ -845,14 +849,14 @@ lfreerdp_cache_bitmapV2(rdpContext* context,
if (cache_bitmap_v2_order->compressed) if (cache_bitmap_v2_order->compressed)
{ {
bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream, bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream,
dst_data, width, height, (tui8*)dst_data, width, height,
cache_bitmap_v2_order->bitmapLength, cache_bitmap_v2_order->bitmapLength,
server_bpp, server_bpp); server_bpp, server_bpp);
} }
else else
{ {
/* Uncompressed bitmaps are upside down */ /* Uncompressed bitmaps are upside down */
lfreerdp_upsidedown(dst_data, cache_bitmap_v2_order, server_Bpp); lfreerdp_upsidedown((tui8*)dst_data, cache_bitmap_v2_order, server_Bpp);
LLOGLN(10, ("lfreerdp_cache_bitmapV2: upside down progressed")); LLOGLN(10, ("lfreerdp_cache_bitmapV2: upside down progressed"));
} }
dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data, dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data,
@ -883,7 +887,7 @@ lfreerdp_cache_glyph(rdpContext* context, CACHE_GLYPH_ORDER* cache_glyph_order)
LLOGLN(10, (" %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y, LLOGLN(10, (" %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y,
gd->cx, gd->cy)); gd->cx, gd->cy));
mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex, mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex,
gd->x, gd->y, gd->cx, gd->cy, gd->aj); gd->x, gd->y, gd->cx, gd->cy, (char*)(gd->aj));
xfree(gd->aj); xfree(gd->aj);
gd->aj = 0; gd->aj = 0;
xfree(gd); xfree(gd);
@ -1089,14 +1093,14 @@ lfreerdp_pointer_new(rdpContext* context,
mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos; mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos; mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
dst = mod->pointer_cache[index].data; dst = (tui8*)(mod->pointer_cache[index].data);
dst += 32 * 32 * 3 - 32 * 3; dst += 32 * 32 * 3 - 32 * 3;
src = pointer_new->colorPtrAttr.xorMaskData; src = pointer_new->colorPtrAttr.xorMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3, lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3,
src, 32, 32, 1, 32 / 8); src, 32, 32, 1, 32 / 8);
dst = mod->pointer_cache[index].mask; dst = (tui8*)(mod->pointer_cache[index].mask);
dst += 32 * 32 / 8 - 32 / 8; dst +=( 32 * 32 / 8) - (32 / 8);
src = pointer_new->colorPtrAttr.andMaskData; src = pointer_new->colorPtrAttr.andMaskData;
lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8, lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
src, 32, 32, 1, 32 / 8); src, 32, 32, 1, 32 / 8);
@ -1205,6 +1209,14 @@ lfreerdp_pre_connect(freerdp* instance)
instance->settings->username = g_strdup(mod->username); instance->settings->username = g_strdup(mod->username);
instance->settings->password = g_strdup(mod->password); instance->settings->password = g_strdup(mod->password);
if (mod->client_info.rail_support_level > 0)
{
instance->settings->remote_app = true;
instance->settings->rail_langbar_supported = true;
instance->settings->workarea = true;
instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
}
// here // here
//instance->settings->rdp_version = 4; //instance->settings->rdp_version = 4;
@ -1245,6 +1257,263 @@ lfreerdp_pre_connect(freerdp* instance)
return true; return true;
} }
/*****************************************************************************/
void DEFAULT_CC
lrail_WindowCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
WINDOW_STATE_ORDER* window_state)
{
int index;
struct mod* mod;
struct rail_window_state_order wso;
UNICONV* uniconv;
LLOGLN(0, ("llrail_WindowCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context*)context)->modi;
memset(&wso, 0, sizeof(wso));
/* copy the window state order */
wso.owner_window_id = window_state->ownerWindowId;
wso.style = window_state->style;
wso.extended_style = window_state->extendedStyle;
wso.show_state = window_state->showState;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
{
wso.title_info = freerdp_uniconv_in(uniconv,
window_state->titleInfo.string, window_state->titleInfo.length);
}
LLOGLN(0, ("lrail_WindowCreate: %s", wso.title_info));
wso.client_offset_x = window_state->clientOffsetX;
wso.client_offset_y = window_state->clientOffsetY;
wso.client_area_width = window_state->clientAreaWidth;
wso.client_area_height = window_state->clientAreaHeight;
wso.rp_content = window_state->RPContent;
wso.root_parent_handle = window_state->rootParentHandle;
wso.window_offset_x = window_state->windowOffsetX;
wso.window_offset_y = window_state->windowOffsetY;
wso.window_client_delta_x = window_state->windowClientDeltaX;
wso.window_client_delta_y = window_state->windowClientDeltaY;
wso.window_width = window_state->windowWidth;
wso.window_height = window_state->windowHeight;
wso.num_window_rects = window_state->numWindowRects;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
{
wso.window_rects = (struct rail_window_rect*)
g_malloc(sizeof(struct rail_window_rect) * wso.num_window_rects, 0);
for (index = 0; index < wso.num_window_rects; index++)
{
wso.window_rects[index].left = window_state->windowRects[index].left;
wso.window_rects[index].top = window_state->windowRects[index].top;
wso.window_rects[index].right = window_state->windowRects[index].right;
wso.window_rects[index].bottom = window_state->windowRects[index].bottom;
}
}
wso.visible_offset_x = window_state->visibleOffsetX;
wso.visible_offset_y = window_state->visibleOffsetY;
wso.num_visibility_rects = window_state->numVisibilityRects;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
{
wso.visibility_rects = (struct rail_window_rect*)
g_malloc(sizeof(struct rail_window_rect) * wso.num_visibility_rects, 0);
for (index = 0; index < wso.num_visibility_rects; index++)
{
wso.visibility_rects[index].left = window_state->visibilityRects[index].left;
wso.visibility_rects[index].top = window_state->visibilityRects[index].top;
wso.visibility_rects[index].right = window_state->visibilityRects[index].right;
wso.visibility_rects[index].bottom = window_state->visibilityRects[index].bottom;
}
}
mod->server_window_new_update(mod, orderInfo->windowId, &wso,
orderInfo->fieldFlags);
xfree(wso.title_info);
g_free(wso.window_rects);
g_free(wso.visibility_rects);
freerdp_uniconv_free(uniconv);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_WindowUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
WINDOW_STATE_ORDER* window_state)
{
LLOGLN(0, ("lrail_WindowUpdate:"));
lrail_WindowCreate(context, orderInfo, window_state);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_WindowDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
struct mod* mod;
LLOGLN(0, ("lrail_WindowDelete:"));
mod = ((struct mod_context*)context)->modi;
mod->server_window_delete(mod, orderInfo->windowId);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_WindowIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
WINDOW_ICON_ORDER* window_icon)
{
struct mod* mod;
struct rail_icon_info rii;
LLOGLN(0, ("lrail_WindowIcon:"));
mod = ((struct mod_context*)context)->modi;
memset(&rii, 0, sizeof(rii));
rii.bpp = window_icon->iconInfo->bpp;
rii.width = window_icon->iconInfo->width;
rii.height = window_icon->iconInfo->height;
rii.cmap_bytes = window_icon->iconInfo->cbColorTable;
rii.mask_bytes = window_icon->iconInfo->cbBitsMask;
rii.data_bytes = window_icon->iconInfo->cbBitsColor;
rii.mask = (char*)(window_icon->iconInfo->bitsMask);
rii.cmap = (char*)(window_icon->iconInfo->colorTable);
rii.data = (char*)(window_icon->iconInfo->bitsColor);
mod->server_window_icon(mod, orderInfo->windowId,
window_icon->iconInfo->cacheEntry,
window_icon->iconInfo->cacheId, &rii,
orderInfo->fieldFlags);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_WindowCachedIcon(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
WINDOW_CACHED_ICON_ORDER* window_cached_icon)
{
struct mod* mod;
LLOGLN(0, ("lrail_WindowCachedIcon:"));
mod = ((struct mod_context*)context)->modi;
mod->server_window_cached_icon(mod, orderInfo->windowId,
window_cached_icon->cachedIcon.cacheEntry,
window_cached_icon->cachedIcon.cacheId,
orderInfo->fieldFlags);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_NotifyIconCreate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
NOTIFY_ICON_STATE_ORDER* notify_icon_state)
{
struct mod* mod;
struct rail_notify_state_order rnso;
UNICONV* uniconv;
LLOGLN(0, ("lrail_NotifyIconCreate:"));
uniconv = freerdp_uniconv_new();
mod = ((struct mod_context*)context)->modi;
memset(&rnso, 0, sizeof(rnso));
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.state = notify_icon_state->state;
rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry;
rnso.icon_cache_id = notify_icon_state->icon.cacheId;
rnso.icon_info.bpp = notify_icon_state->icon.bpp;
rnso.icon_info.width = notify_icon_state->icon.width;
rnso.icon_info.height = notify_icon_state->icon.height;
rnso.icon_info.cmap_bytes = notify_icon_state->icon.cbColorTable;
rnso.icon_info.mask_bytes = notify_icon_state->icon.cbBitsMask;
rnso.icon_info.data_bytes = notify_icon_state->icon.cbBitsColor;
rnso.icon_info.mask = (char*)(notify_icon_state->icon.bitsMask);
rnso.icon_info.cmap = (char*)(notify_icon_state->icon.colorTable);
rnso.icon_info.data = (char*)(notify_icon_state->icon.bitsColor);
mod->server_notify_new_update(mod, orderInfo->windowId,
orderInfo->notifyIconId,
&rnso, orderInfo->fieldFlags);
xfree(rnso.tool_tip);
xfree(rnso.infotip.text);
xfree(rnso.infotip.title);
freerdp_uniconv_free(uniconv);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_NotifyIconUpdate(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
NOTIFY_ICON_STATE_ORDER* notify_icon_state)
{
LLOGLN(0, ("lrail_NotifyIconUpdate:"));
lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_NotifyIconDelete(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
struct mod* mod;
LLOGLN(0, ("lrail_NotifyIconDelete:"));
mod = ((struct mod_context*)context)->modi;
mod->server_notify_delete(mod, orderInfo->windowId,
orderInfo->notifyIconId);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_MonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo,
MONITORED_DESKTOP_ORDER* monitored_desktop)
{
int index;
struct mod* mod;
struct rail_monitored_desktop_order rmdo;
LLOGLN(0, ("lrail_MonitoredDesktop:"));
mod = ((struct mod_context*)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
rmdo.active_window_id = monitored_desktop->activeWindowId;
rmdo.num_window_ids = monitored_desktop->numWindowIds;
if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
{
if (rmdo.num_window_ids > 0)
{
rmdo.window_ids = (int*)g_malloc(sizeof(int) * rmdo.num_window_ids, 0);
for (index = 0; index < rmdo.num_window_ids; index++)
{
rmdo.window_ids[index] = monitored_desktop->windowIds[index];
}
}
}
mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
g_free(rmdo.window_ids);
}
/*****************************************************************************/
void DEFAULT_CC
lrail_NonMonitoredDesktop(rdpContext* context, WINDOW_ORDER_INFO* orderInfo)
{
struct mod* mod;
struct rail_monitored_desktop_order rmdo;
LLOGLN(0, ("lrail_NonMonitoredDesktop:"));
mod = ((struct mod_context*)context)->modi;
memset(&rmdo, 0, sizeof(rmdo));
mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
}
/******************************************************************************/ /******************************************************************************/
static boolean DEFAULT_CC static boolean DEFAULT_CC
lfreerdp_post_connect(freerdp* instance) lfreerdp_post_connect(freerdp* instance)
@ -1254,6 +1523,18 @@ lfreerdp_post_connect(freerdp* instance)
LLOGLN(0, ("lfreerdp_post_connect:")); LLOGLN(0, ("lfreerdp_post_connect:"));
mod = ((struct mod_context*)(instance->context))->modi; mod = ((struct mod_context*)(instance->context))->modi;
g_memset(mod->password, 0, sizeof(mod->password)); g_memset(mod->password, 0, sizeof(mod->password));
mod->inst->update->window->WindowCreate = lrail_WindowCreate;
mod->inst->update->window->WindowUpdate = lrail_WindowUpdate;
mod->inst->update->window->WindowDelete = lrail_WindowDelete;
mod->inst->update->window->WindowIcon = lrail_WindowIcon;
mod->inst->update->window->WindowCachedIcon = lrail_WindowCachedIcon;
mod->inst->update->window->NotifyIconCreate = lrail_NotifyIconCreate;
mod->inst->update->window->NotifyIconUpdate = lrail_NotifyIconUpdate;
mod->inst->update->window->NotifyIconDelete = lrail_NotifyIconDelete;
mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop;
mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop;
return true; return true;
} }
@ -1294,7 +1575,7 @@ lfreerdp_receive_channel_data(freerdp* instance, int channelId, uint8* data,
if (lchid >= 0) if (lchid >= 0)
{ {
LLOGLN(10, ("lfreerdp_receive_channel_data: server to client")); LLOGLN(10, ("lfreerdp_receive_channel_data: server to client"));
error = mod->server_send_to_channel(mod, lchid, data, size, error = mod->server_send_to_channel(mod, lchid, (char*)data, size,
total_size, flags); total_size, flags);
if (error != 0) if (error != 0)
{ {
@ -1379,7 +1660,7 @@ mod_exit(struct mod* mod)
{ {
return 0; return 0;
} }
if(mod->inst == NULL) if (mod->inst == NULL)
{ {
LLOGLN(0, ("mod_exit - null pointer for inst:")); LLOGLN(0, ("mod_exit - null pointer for inst:"));
g_free(mod); g_free(mod);

@ -22,9 +22,15 @@
#include "parse.h" #include "parse.h"
#include "os_calls.h" #include "os_calls.h"
#include "defines.h" #include "defines.h"
#include "xrdp_rail.h"
#include "xrdp_client_info.h"
/* this is the freerdp main header */ /* this is the freerdp main header */
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/rail.h>
#include <freerdp/rail/rail.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/utils/memory.h>
//#include "/home/jay/git/jsorg71/staging/include/freerdp/freerdp.h" //#include "/home/jay/git/jsorg71/staging/include/freerdp/freerdp.h"
struct bitmap_item struct bitmap_item
@ -112,7 +118,38 @@ struct mod
char* data, int data_len, char* data, int data_len,
int total_data_len, int flags); int total_data_len, int flags);
int (*server_bell_trigger)(struct mod* v); int (*server_bell_trigger)(struct mod* v);
long server_dumby[100 - 25]; /* align, 100 minus the number of server /* off screen bitmaps */
int (*server_create_os_surface)(struct mod* v, int rdpindex,
int width, int height);
int (*server_switch_os_surface)(struct mod* v, int rdpindex);
int (*server_delete_os_surface)(struct mod* v, int rdpindex);
int (*server_paint_rect_os)(struct mod* mod, int x, int y,
int cx, int cy,
int rdpindex, int srcx, int srcy);
int (*server_set_hints)(struct mod* mod, int hints, int mask);
/* rail */
int (*server_window_new_update)(struct mod* mod, int window_id,
struct rail_window_state_order* window_state,
int flags);
int (*server_window_delete)(struct mod* mod, int window_id);
int (*server_window_icon)(struct mod* mod,
int window_id, int cache_entry, int cache_id,
struct rail_icon_info* icon_info,
int flags);
int (*server_window_cached_icon)(struct mod* mod,
int window_id, int cache_entry,
int cache_id, int flags);
int (*server_notify_new_update)(struct mod* mod,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
int flags);
int (*server_notify_delete)(struct mod* mod, int window_id,
int notify_id);
int (*server_monitored_desktop)(struct mod* mod,
struct rail_monitored_desktop_order* mdo,
int flags);
long server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tbus handle; /* pointer to self as long */ tbus handle; /* pointer to self as long */
@ -133,6 +170,8 @@ struct mod
char username[256]; char username[256];
char password[256]; char password[256];
struct xrdp_client_info client_info;
struct rdp_freerdp* inst; struct rdp_freerdp* inst;
struct bitmap_item bitmap_cache[4][4096]; struct bitmap_item bitmap_cache[4][4096];
struct brush_item brush_cache[64]; struct brush_item brush_cache[64];

@ -80,7 +80,7 @@ libxrdp_process_data(struct xrdp_session* session)
term = 0; term = 0;
cont = 1; cont = 1;
rv = 0; rv = 0;
dead_lock_counter = 0 ; dead_lock_counter = 0;
while ((cont || !session->up_and_running) && !term) while ((cont || !session->up_and_running) && !term)
{ {
if (session->is_term != 0) if (session->is_term != 0)
@ -91,7 +91,8 @@ libxrdp_process_data(struct xrdp_session* session)
} }
} }
code = 0; code = 0;
if (xrdp_rdp_recv((struct xrdp_rdp*)session->rdp, session->s, &code) != 0) if (xrdp_rdp_recv((struct xrdp_rdp*)(session->rdp),
session->s, &code) != 0)
{ {
rv = 1; rv = 1;
break; break;
@ -104,7 +105,7 @@ libxrdp_process_data(struct xrdp_session* session)
session->up_and_running = 0; session->up_and_running = 0;
break; break;
case 0: case 0:
dead_lock_counter ++ ; dead_lock_counter++;
break; break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp, xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp,
@ -121,13 +122,13 @@ libxrdp_process_data(struct xrdp_session* session)
break; break;
default: default:
g_writeln("unknown in libxrdp_process_data"); g_writeln("unknown in libxrdp_process_data");
dead_lock_counter ++ ; dead_lock_counter++;
break; break;
} }
if(dead_lock_counter>100000) if (dead_lock_counter > 100000)
{ {
/*This situation can happen and this is a workaround*/ /*This situation can happen and this is a workaround*/
cont = 0 ; cont = 0;
g_writeln("Serious programming error we were locked in a deadly loop") ; g_writeln("Serious programming error we were locked in a deadly loop") ;
g_writeln("remaining :%d",session->s->end-session->s->next_packet); g_writeln("remaining :%d",session->s->end-session->s->next_packet);
session->s->next_packet = 0; session->s->next_packet = 0;
@ -628,9 +629,9 @@ libxrdp_reset(struct xrdp_session* session,
} }
/* process till up and running */ /* process till up and running */
session->up_and_running = 0; session->up_and_running = 0;
if(libxrdp_process_data(session)!=0) if (libxrdp_process_data(session) != 0)
{ {
g_writeln("non handled error from libxrdp_process_data"); g_writeln("non handled error from libxrdp_process_data");
} }
return 0; return 0;
} }
@ -673,7 +674,7 @@ libxrdp_query_channel(struct xrdp_session* session, int index,
rdp = (struct xrdp_rdp*)session->rdp; rdp = (struct xrdp_rdp*)session->rdp;
mcs = rdp->sec_layer->mcs_layer; mcs = rdp->sec_layer->mcs_layer;
if(mcs->channel_list==NULL) if (mcs->channel_list == NULL)
{ {
g_writeln("libxrdp_query_channel - No channel initialized"); g_writeln("libxrdp_query_channel - No channel initialized");
return 1 ; return 1 ;
@ -688,7 +689,7 @@ libxrdp_query_channel(struct xrdp_session* session, int index,
if (channel_item == 0) if (channel_item == 0)
{ {
/* this should not happen */ /* this should not happen */
g_writeln("libxrdp_query_channel - channel item is 0"); g_writeln("libxrdp_query_channel - channel item is 0");
return 1; return 1;
} }
if (channel_name != 0) if (channel_name != 0)
@ -716,7 +717,7 @@ libxrdp_get_channel_id(struct xrdp_session* session, char* name)
rdp = (struct xrdp_rdp*)session->rdp; rdp = (struct xrdp_rdp*)session->rdp;
mcs = rdp->sec_layer->mcs_layer; mcs = rdp->sec_layer->mcs_layer;
if(mcs->channel_list==NULL) if (mcs->channel_list == NULL)
{ {
g_writeln("libxrdp_get_channel_id No channel initialized"); g_writeln("libxrdp_get_channel_id No channel initialized");
return -1 ; return -1 ;
@ -763,7 +764,7 @@ libxrdp_send_to_channel(struct xrdp_session* session, int channel_id,
s_mark_end(s); s_mark_end(s);
if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
{ {
g_writeln("Debug - data NOT sent to channel"); g_writeln("Debug - data NOT sent to channel");
free_stream(s); free_stream(s);
return 1; return 1;
} }
@ -800,3 +801,89 @@ libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id)
return xrdp_orders_send_switch_os_surface return xrdp_orders_send_switch_os_surface
((struct xrdp_orders*)(session->orders), id); ((struct xrdp_orders*)(session->orders), id);
} }
/*****************************************************************************/
int EXPORT_CC
libxrdp_window_new_update(struct xrdp_session* session, int window_id,
struct rail_window_state_order* window_state,
int flags)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_window_new_update(orders, window_id,
window_state, flags);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_window_delete(struct xrdp_session* session, int window_id)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_window_delete(orders, window_id);
}
/*****************************************************************************/
int EXPORT_CC
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 xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_window_icon(orders, window_id, cache_entry,
cache_id, icon_info, flags);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_window_cached_icon(struct xrdp_session* session, int window_id,
int cache_entry, int cache_id,
int flags)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry,
cache_id, flags);
}
/*****************************************************************************/
int EXPORT_CC
libxrdp_notify_new_update(struct xrdp_session* session,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
int flags)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_notify_new_update(orders, window_id, notify_id,
notify_state, flags);
}
/*****************************************************************************/
int DEFAULT_CC
libxrdp_notify_delete(struct xrdp_session* session,
int window_id, int notify_id)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_notify_delete(orders, window_id, notify_id);
}
/*****************************************************************************/
int DEFAULT_CC
libxrdp_monitored_desktop(struct xrdp_session* session,
struct rail_monitored_desktop_order* mdo,
int flags)
{
struct xrdp_orders* orders;
orders = (struct xrdp_orders*)(session->orders);
return xrdp_orders_send_monitored_desktop(orders, mdo, flags);
}

@ -23,6 +23,8 @@
#ifndef LIBXRDPINC_H #ifndef LIBXRDPINC_H
#define LIBXRDPINC_H #define LIBXRDPINC_H
#include "xrdp_rail.h"
/* struct xrdp_client_info moved to xrdp_client_info.h */ /* struct xrdp_client_info moved to xrdp_client_info.h */
struct xrdp_brush struct xrdp_brush
@ -176,11 +178,37 @@ 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 width, int height, int bpp, int type,
int size, char* data, int cache_id); int size, char* data, int cache_id);
int EXPORT_CC 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, int width, int height,
struct list* del_list); struct list* del_list);
int EXPORT_CC 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,
int flags);
int DEFAULT_CC
libxrdp_window_delete(struct xrdp_session* session, int window_id);
int DEFAULT_CC
libxrdp_window_icon(struct xrdp_session* session, int window_id,
int cache_entry, int cache_id,
struct rail_icon_info* icon_info, int flags);
int DEFAULT_CC
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,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
int flags);
int DEFAULT_CC
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,
int flags);
#endif #endif

@ -17,7 +17,7 @@
*/ */
#include "libxrdp.h" #include "libxrdp.h"
#include "rail.h" #include "xrdp_rail.h"
/* [MS-RDPERP]: Remote Desktop Protocol: /* [MS-RDPERP]: Remote Desktop Protocol:
Remote Programs Virtual Channel Extension Remote Programs Virtual Channel Extension

@ -417,7 +417,7 @@ server_draw_text(struct xrdp_mod* mod, int font,
int x, int y, char* data, int data_len); int x, int y, char* data, int data_len);
int DEFAULT_CC int DEFAULT_CC
server_reset(struct xrdp_mod* mod, int width, int height, int bpp); server_reset(struct xrdp_mod* mod, int width, int height, int bpp);
int DEFAULT_CC int DEFAULT_CC
is_channel_allowed(struct xrdp_wm* wm, int channel_id); is_channel_allowed(struct xrdp_wm* wm, int channel_id);
int DEFAULT_CC int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
@ -440,3 +440,29 @@ server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy,
int id, int srcx, int srcy); int id, int srcx, int srcy);
int DEFAULT_CC int DEFAULT_CC
server_set_hints(struct xrdp_mod* mod, int hints, int mask); server_set_hints(struct xrdp_mod* mod, int hints, int mask);
int DEFAULT_CC
server_window_new_update(struct xrdp_mod* mod, int window_id,
struct rail_window_state_order* window_state,
int flags);
int DEFAULT_CC
server_window_delete(struct xrdp_mod* mod, int 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);
int DEFAULT_CC
server_window_cached_icon(struct xrdp_mod* mod,
int window_id, int cache_entry,
int cache_id, int 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);
int DEFAULT_CC
server_notify_delete(struct xrdp_mod* mod, int window_id,
int notify_id);
int DEFAULT_CC
server_monitored_desktop(struct xrdp_mod* mod,
struct rail_monitored_desktop_order* mdo,
int flags);

@ -285,7 +285,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
} }
if (self->mod_handle == 0) if (self->mod_handle == 0)
{ {
/* Let the main thread load the lib,*/ /* Let the main thread load the lib,*/
self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0); self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0);
if (self->mod_handle != 0) if (self->mod_handle != 0)
{ {
@ -330,7 +330,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please " g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please "
"add a valid entry like lib=libxrdp-vnc.so or similar", lib); "add a valid entry like lib=libxrdp-vnc.so or similar", lib);
xrdp_wm_log_msg(self->wm, text); xrdp_wm_log_msg(self->wm, text);
return 1 ; return 1;
} }
if (self->mod != 0) if (self->mod != 0)
{ {
@ -808,7 +808,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: " xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
"login failed"); "login failed");
} }
cleanup_sesman_connection(self); cleanup_sesman_connection(self);
return rv; return rv;
} }
@ -942,14 +942,14 @@ xrdp_mm_sesman_data_in(struct trans* trans)
in_uint16_be(s, code); in_uint16_be(s, code);
switch (code) switch (code)
{ {
/* even when the request is denied the reply will hold 3 as the command. */ /* even when the request is denied the reply will hold 3 as the command. */
case 3: case 3:
error = xrdp_mm_process_login_response(self, s); error = xrdp_mm_process_login_response(self, s);
break; break;
default: default:
xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman"); 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); g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
cleanup_sesman_connection(self); cleanup_sesman_connection(self);
break; break;
} }
} }
@ -960,117 +960,120 @@ xrdp_mm_sesman_data_in(struct trans* trans)
#ifdef ACCESS #ifdef ACCESS
/*********************************************************************/ /*********************************************************************/
/* return 0 on success */ /* return 0 on success */
int access_control(char *username, char *password, char *srv){ int access_control(char *username, char *password, char *srv)
int reply ; {
int rec = 1 ; // failure int reply;
int rec = 1; // failure
struct stream* in_s; struct stream* in_s;
struct stream* out_s; struct stream* out_s;
unsigned long version ; unsigned long version;
unsigned short int dummy; unsigned short int dummy;
unsigned short int ok; unsigned short int ok;
unsigned short int code; unsigned short int code;
unsigned long size ; unsigned long size;
int index ; int index;
int socket = g_tcp_socket(); int socket = g_tcp_socket();
if (socket > 0) { if (socket > 0)
{
/* we use a blocking socket here */ /* we use a blocking socket here */
reply = g_tcp_connect(socket, srv, "3350"); reply = g_tcp_connect(socket, srv, "3350");
if (reply == 0) if (reply == 0)
{ {
make_stream(in_s); make_stream(in_s);
init_stream(in_s, 500); init_stream(in_s, 500);
make_stream(out_s); make_stream(out_s);
init_stream(out_s, 500); init_stream(out_s, 500);
s_push_layer(out_s, channel_hdr, 8); s_push_layer(out_s, channel_hdr, 8);
out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/ out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/
index = g_strlen(username); index = g_strlen(username);
out_uint16_be(out_s, index); out_uint16_be(out_s, index);
out_uint8a(out_s, username, index); out_uint8a(out_s, username, index);
index = g_strlen(password); index = g_strlen(password);
out_uint16_be(out_s, index); out_uint16_be(out_s, index);
out_uint8a(out_s, password, index); out_uint8a(out_s, password, index);
s_mark_end(out_s); s_mark_end(out_s);
s_pop_layer(out_s, channel_hdr); s_pop_layer(out_s, channel_hdr);
out_uint32_be(out_s, 0); /* version */ out_uint32_be(out_s, 0); /* version */
index = (int)(out_s->end - out_s->data); index = (int)(out_s->end - out_s->data);
out_uint32_be(out_s, index); /* size */ out_uint32_be(out_s, index); /* size */
/* g_writeln("Number of data to send : %d",index); */ /* g_writeln("Number of data to send : %d",index); */
reply = g_tcp_send(socket, out_s->data, index, 0); reply = g_tcp_send(socket, out_s->data, index, 0);
free_stream(out_s); free_stream(out_s);
if (reply > 0) if (reply > 0)
{ {
/* We wait in 5 sec for a reply from sesman*/ /* We wait in 5 sec for a reply from sesman*/
if(g_tcp_can_recv(socket,5000)){ if (g_tcp_can_recv(socket, 5000))
{
reply = g_tcp_recv(socket, in_s->end, 500, 0); reply = g_tcp_recv(socket, in_s->end, 500, 0);
if (reply > 0) if (reply > 0)
{ {
in_s->end = in_s->end + reply ; in_s->end = in_s->end + reply;
in_uint32_be(in_s, version); in_uint32_be(in_s, version);
/*g_writeln("Version number in reply from sesman: %d",version) ; */ /*g_writeln("Version number in reply from sesman: %d",version) ; */
in_uint32_be(in_s, size); in_uint32_be(in_s, size);
if((size==14) && (version==0)) if ((size == 14) && (version == 0))
{ {
in_uint16_be(in_s, code); in_uint16_be(in_s, code);
in_uint16_be(in_s, ok); in_uint16_be(in_s, ok);
in_uint16_be(in_s, dummy); in_uint16_be(in_s, dummy);
if(code!=4) if (code != 4)
{ {
log_message(LOG_LEVEL_ERROR,"Returned cmd code from " log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
"sesman is corrupt"); "sesman is corrupt");
} }
else else
{ {
rec = ok; /* here we read the reply from the access control */ rec = ok; /* here we read the reply from the access control */
} }
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"Corrupt reply size or " log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
"version from sesman: %d",size); "version from sesman: %d", size);
} }
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"No data received from sesman"); log_message(LOG_LEVEL_ERROR, "No data received from sesman");
} }
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"Timeout when waiting for sesman"); log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman");
} }
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"No success sending to sesman"); log_message(LOG_LEVEL_ERROR, "No success sending to sesman");
} }
free_stream(in_s); free_stream(in_s);
g_tcp_close(socket); g_tcp_close(socket);
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"Failure connecting to socket sesman"); log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman");
} }
} }
else else
{ {
log_message(LOG_LEVEL_ERROR,"Failure creating socket - for access control"); log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
} }
return rec; return rec;
} }
#endif #endif
/*****************************************************************************/ /*****************************************************************************/
/* This routine clears all states to make sure that our next login will be /* 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 * 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.*/ * connect again we must make sure that no previous information is stored.*/
void cleanup_states(struct xrdp_mm* self) void cleanup_states(struct xrdp_mm* self)
{ {
if(self != NULL) if (self != NULL)
{ {
self-> connected_state = 0; /* true if connected to sesman else false */ self-> connected_state = 0; /* true if connected to sesman else false */
self-> sesman_trans = NULL; /* connection to sesman */ self-> sesman_trans = NULL; /* connection to sesman */
self-> sesman_trans_up = 0 ; /* true once connected 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-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */ 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 */
@ -1099,8 +1102,8 @@ xrdp_mm_connect(struct xrdp_mm* self)
char port[8]; char port[8];
char chansrvport[256]; char chansrvport[256];
#ifdef ACCESS #ifdef ACCESS
int use_pam_auth = 0 ; int use_pam_auth = 0;
char pam_auth_sessionIP[256] ; char pam_auth_sessionIP[256];
char pam_auth_password[256]; char pam_auth_password[256];
char pam_auth_username[256]; char pam_auth_username[256];
char username[256]; char username[256];
@ -1134,28 +1137,28 @@ xrdp_mm_connect(struct xrdp_mm* self)
self->sesman_controlled = 1; self->sesman_controlled = 1;
} }
} }
#ifdef ACCESS #ifdef ACCESS
else if (g_strcasecmp(name, "pamusername") == 0) else if (g_strcasecmp(name, "pamusername") == 0)
{ {
use_pam_auth = 1; use_pam_auth = 1;
g_strncpy(pam_auth_username, value, 255); g_strncpy(pam_auth_username, value, 255);
} }
else if (g_strcasecmp(name, "pamsessionmng") == 0) else if (g_strcasecmp(name, "pamsessionmng") == 0)
{ {
g_strncpy(pam_auth_sessionIP, value, 255); g_strncpy(pam_auth_sessionIP, value, 255);
} }
else if (g_strcasecmp(name, "pampassword") == 0) else if (g_strcasecmp(name, "pampassword") == 0)
{ {
g_strncpy(pam_auth_password, value, 255); g_strncpy(pam_auth_password, value, 255);
} }
else if (g_strcasecmp(name, "password") == 0) else if (g_strcasecmp(name, "password") == 0)
{ {
g_strncpy(password, value, 255); g_strncpy(password, value, 255);
} }
else if (g_strcasecmp(name, "username") == 0) else if (g_strcasecmp(name, "username") == 0)
{ {
g_strncpy(username, value, 255); g_strncpy(username, value, 255);
} }
#endif #endif
else if (g_strcasecmp(name, "chansrvport") == 0) else if (g_strcasecmp(name, "chansrvport") == 0)
{ {
@ -1163,28 +1166,29 @@ xrdp_mm_connect(struct xrdp_mm* self)
self->usechansrv = 1; self->usechansrv = 1;
} }
} }
#ifdef ACCESS #ifdef ACCESS
if(use_pam_auth){ if (use_pam_auth)
int reply; {
int reply;
char replytxt[80]; char replytxt[80];
char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"}; 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..."); 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"); */ /* g_writeln("we use pam modules to check if we can approve this user"); */
if(!g_strncmp(pam_auth_username,"same",255)) if (!g_strncmp(pam_auth_username, "same", 255))
{ {
log_message(LOG_LEVEL_DEBUG,"pamusername copied from username - same: %s",username); log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username);
g_strncpy(pam_auth_username,username,255); g_strncpy(pam_auth_username,username, 255);
} }
if(!g_strncmp(pam_auth_password,"same",255)) if (!g_strncmp(pam_auth_password, "same", 255))
{ {
log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s",password); log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password);
g_strncpy(pam_auth_password,password,255); g_strncpy(pam_auth_password, password, 255);
} }
/* access_control return 0 on success */ /* access_control return 0 on success */
reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP); reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
if(reply>=0 && reply<4) if (reply >= 0 && reply < 4)
{ {
g_sprintf(replytxt,"Reply from access control: %s",replymessage[reply]); g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]);
} }
else else
{ {
@ -1192,12 +1196,12 @@ xrdp_mm_connect(struct xrdp_mm* self)
} }
xrdp_wm_log_msg(self->wm,replytxt); xrdp_wm_log_msg(self->wm,replytxt);
log_message(LOG_LEVEL_INFO,replytxt); log_message(LOG_LEVEL_INFO,replytxt);
if(reply!=0) if (reply != 0)
{ {
rv = 1 ; rv = 1;
return rv ; return rv;
} }
} }
#endif #endif
if (self->sesman_controlled) if (self->sesman_controlled)
{ {
@ -1234,7 +1238,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
else else
{ {
g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s", g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
ip, port); ip, port);
xrdp_wm_log_msg(self->wm, errstr); xrdp_wm_log_msg(self->wm, errstr);
trans_delete(self->sesman_trans); trans_delete(self->sesman_trans);
self->sesman_trans = 0; self->sesman_trans = 0;
@ -1249,12 +1253,12 @@ xrdp_mm_connect(struct xrdp_mm* self)
if (xrdp_mm_setup_mod2(self) == 0) if (xrdp_mm_setup_mod2(self) == 0)
{ {
xrdp_wm_set_login_mode(self->wm, 10); xrdp_wm_set_login_mode(self->wm, 10);
rv = 0 ; /*sucess*/ rv = 0; /*sucess*/
} }
else else
{ {
/* connect error */ /* connect error */
g_snprintf(errstr, 255, "Failure to connect to: %s",ip); g_snprintf(errstr, 255, "Failure to connect to: %s", ip);
xrdp_wm_log_msg(self->wm, errstr); xrdp_wm_log_msg(self->wm, errstr);
rv = 1; /* failure */ rv = 1; /* failure */
} }
@ -1267,7 +1271,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
{ {
xrdp_wm_set_login_mode(self->wm, 11); xrdp_wm_set_login_mode(self->wm, 11);
xrdp_mm_module_cleanup(self); xrdp_mm_module_cleanup(self);
rv = 1 ; /* failure */ rv = 1; /* failure */
} }
} }
@ -1277,7 +1281,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
/* if sesman controlled, this will connect later */ /* if sesman controlled, this will connect later */
xrdp_mm_connect_chansrv(self, "", chansrvport); xrdp_mm_connect_chansrv(self, "", chansrvport);
} }
g_writeln("returnvalue from xrdp_mm_connect %d",rv); g_writeln("returnvalue from xrdp_mm_connect %d", rv);
return rv; return rv;
} }
@ -1760,154 +1764,161 @@ server_reset(struct xrdp_mod* mod, int width, int height, int bpp)
* return 1 on success 0 on failure */ * return 1 on success 0 on failure */
int read_allowed_channel_names(struct list* names, struct list* values) int read_allowed_channel_names(struct list* names, struct list* values)
{ {
int fd; int fd;
int ret = 0 ; int ret = 0;
char cfg_file[256]; char cfg_file[256];
int pos; int pos;
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
fd = g_file_open(cfg_file); fd = g_file_open(cfg_file);
if (fd > 0) if (fd > 0)
{ {
names->auto_free = 1; names->auto_free = 1;
values->auto_free = 1; values->auto_free = 1;
pos = 0 ; pos = 0;
/* all values in this section can be valid channel names */ /* all values in this section can be valid channel names */
if (file_read_section(fd, "channels", names, values) == 0) if (file_read_section(fd, "channels", names, values) == 0)
{ {
ret = 1 ; ret = 1;
} }
else else
{ {
g_writeln("Failure reading channel section of configuration") ; g_writeln("Failure reading channel section of configuration");
} }
g_file_close(fd); g_file_close(fd);
return ret ; return ret;
} }
} }
/* internal function return 1 if name is in list of channels /* internal function return 1 if name is in list of channels
* and if the value is allowed */ * and if the value is allowed */
int DEFAULT_CC is_name_in_lists(char *inName, struct list* names, struct list* values) int DEFAULT_CC
is_name_in_lists(char* inName, struct list* names, struct list* values)
{ {
int reply = 0 ; /*means not in the list*/ int reply = 0; /*means not in the list*/
int index ; int index;
char* val; char* val;
char* name ; char* name;
for (index = 0; index < names->count; index++) for (index = 0; index < names->count; index++)
{ {
name = (char*)list_get_item(names, index); name = (char*)list_get_item(names, index);
if (name != 0) if (name != 0)
{ {
/* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */ /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */
if(!g_strncmp(name,inName,MAX_CHANNEL_NAME)){ if (!g_strncmp(name, inName, MAX_CHANNEL_NAME))
{
val = (char*)list_get_item(values, index); val = (char*)list_get_item(values, index);
if ((g_strcasecmp(val, "yes") == 0) || if ((g_strcasecmp(val, "yes") == 0) ||
(g_strcasecmp(val, "on") == 0) || (g_strcasecmp(val, "on") == 0) ||
(g_strcasecmp(val, "true") == 0) || (g_strcasecmp(val, "true") == 0) ||
(g_atoi(val) != 0)) (g_atoi(val) != 0))
{ {
reply = 1 ; reply = 1;
} }
else else
{ {
g_writeln("This channel is disabled: %s",name); g_writeln("This channel is disabled: %s", name);
} }
break ; /* stop loop - item found*/ break; /* stop loop - item found*/
} }
} }
} }
return reply ; return reply;
} }
/* internal function only used once per session /* internal function only used once per session
* creates the list of allowed channels and store the information * creates the list of allowed channels and store the information
* in wm struct */ * in wm struct */
void init_channel_allowed(struct xrdp_wm* wm) void init_channel_allowed(struct xrdp_wm* wm)
{ {
int error ; int error;
int i ; int i;
char channelname[MAX_CHANNEL_NAME]; char channelname[MAX_CHANNEL_NAME];
int index = 0 ; int index = 0;
int allowindex = 0 ; int allowindex = 0;
struct list* names; struct list* names;
struct list* values; struct list* values;
/* first reset allowedchannels */ /* first reset allowedchannels */
for(i = 0 ; i<MAX_NR_CHANNELS;i++) for (i = 0; i < MAX_NR_CHANNELS; i++)
{ {
/* 0 is a valid channel so we use -1 to mark the index as unused */ /* 0 is a valid channel so we use -1 to mark the index as unused */
wm->allowedchannels[i] = -1 ; wm->allowedchannels[i] = -1;
} }
names = list_create(); names = list_create();
values = list_create(); values = list_create();
if(read_allowed_channel_names(names,values)){ if (read_allowed_channel_names(names, values))
do{ {
do
{
/* libxrdp_query_channel return 1 on error*/ /* libxrdp_query_channel return 1 on error*/
error = libxrdp_query_channel(wm->session, index, channelname,NULL); error = libxrdp_query_channel(wm->session, index, channelname,NULL);
if(error==0){ if (error == 0)
/* examples of channel names: rdpdr ;rdpsnd ; drdynvc ; cliprdr */ {
if(is_name_in_lists(channelname,names,values)){ /* examples of channel names: rdpdr ; rdpsnd ; drdynvc ; cliprdr */
g_writeln("The following channel is allowed: %s",channelname) ; if (is_name_in_lists(channelname, names, values))
wm->allowedchannels[allowindex] = index ; {
allowindex ++ ; g_writeln("The following channel is allowed: %s", channelname);
if(allowindex>=MAX_NR_CHANNELS) wm->allowedchannels[allowindex] = index;
allowindex++;
if (allowindex >= MAX_NR_CHANNELS)
{ {
g_writeln("Programming error in is_channel_allowed"); g_writeln("Programming error in is_channel_allowed");
error = 1 ; /* end loop */ error = 1; /* end loop */
} }
} }
else else
{ {
g_writeln("The following channel is not allowed: %s",channelname) ; g_writeln("The following channel is not allowed: %s",channelname);
} }
index ++ ; index++;
} }
}while((error==0) && (index<MAX_NR_CHANNELS)) ; } while ((error == 0) && (index < MAX_NR_CHANNELS));
} }
else else
{ {
g_writeln("Error reading channel section in inifile") ; g_writeln("Error reading channel section in inifile");
} }
list_delete(names); list_delete(names);
list_delete(values); list_delete(values);
} }
/*****************************************************************************/ /*****************************************************************************/
/* This function returns 1 if the channelID is allowed by rule set /* This function returns 1 if the channelID is allowed by rule set
* returns 0 if not allowed */ * returns 0 if not allowed */
int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id) int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id)
{ {
int i ; int i;
int reply = 0 ; /* not allowed */ int reply = 0; /* not allowed */
/* The first time each client is using this function we have to /* The first time each client is using this function we have to
* define the list of allowed channels */ * define the list of allowed channels */
if(wm->allowedinitialized==0) if (wm->allowedinitialized == 0)
{ {
init_channel_allowed(wm); init_channel_allowed(wm);
g_writeln("allow channel list initialized"); g_writeln("allow channel list initialized");
wm->allowedinitialized = 1 ; wm->allowedinitialized = 1;
} }
for(i = 0 ; i<MAX_NR_CHANNELS;i++) for(i = 0; i < MAX_NR_CHANNELS; i++)
{ {
if(channel_id == wm->allowedchannels[i]) if (channel_id == wm->allowedchannels[i])
{ {
/*g_writeln("Channel allowed: %d",channel_id);*/ /*g_writeln("Channel allowed: %d",channel_id);*/
reply = 1 ; /*channel allowed*/ reply = 1; /*channel allowed*/
break ; break;
} }
else if(wm->allowedchannels[i]==-1) else if (wm->allowedchannels[i] == -1)
{ {
/* We are in the unused space of the allowedchannels list /* We are in the unused space of the allowedchannels list
* We can end the loop */ * We can end the loop */
break ; break;
} }
} }
/*if(reply==0) /*if (reply == 0)
{ {
g_writeln("This channel is NOT allowed: %d",channel_id) ; g_writeln("This channel is NOT allowed: %d",channel_id) ;
}*/ }*/
return reply ; return reply;
} }
/*****************************************************************************/ /*****************************************************************************/
/*return 0 if the index is not found*/ /*return 0 if the index is not found*/
int DEFAULT_CC int DEFAULT_CC
server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, server_query_channel(struct xrdp_mod* mod, int index, char* channel_name,
int* channel_flags) int* channel_flags)
{ {
@ -1946,14 +1957,14 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id,
struct xrdp_wm* wm; struct xrdp_wm* wm;
wm = (struct xrdp_wm*)(mod->wm); wm = (struct xrdp_wm*)(mod->wm);
if(is_channel_allowed(wm,channel_id)) if (is_channel_allowed(wm, channel_id))
{ {
if (wm->mm->usechansrv) if (wm->mm->usechansrv)
{ {
return 1; return 1;
} }
return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
total_data_len, flags); total_data_len, flags);
} }
else else
{ {
@ -2101,3 +2112,89 @@ server_set_hints(struct xrdp_mod* mod, int hints, int mask)
} }
return 0; 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);
}

@ -22,6 +22,7 @@
#define DEFAULT_STRING_LEN 255 #define DEFAULT_STRING_LEN 255
#define LOG_WINDOW_CHAR_PER_LINE 60 #define LOG_WINDOW_CHAR_PER_LINE 60
#include "xrdp_rail.h"
#define MAX_NR_CHANNELS 16 #define MAX_NR_CHANNELS 16
#define MAX_CHANNEL_NAME 16 #define MAX_CHANNEL_NAME 16
@ -42,7 +43,7 @@ struct xrdp_mod
int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount, int (*mod_get_wait_objs)(struct xrdp_mod* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout); tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct xrdp_mod* v); int (*mod_check_wait_objs)(struct xrdp_mod* v);
long mod_dumby[100 - 9]; /* align, 100 minus the number of mod long mod_dumby[100 - 9]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct xrdp_mod* v); int (*server_begin_update)(struct xrdp_mod* v);
@ -85,6 +86,7 @@ struct xrdp_mod
char* data, int data_len, char* data, int data_len,
int total_data_len, int flags); int total_data_len, int flags);
int (*server_bell_trigger)(struct xrdp_mod* v); int (*server_bell_trigger)(struct xrdp_mod* v);
/* off screen bitmaps */
int (*server_create_os_surface)(struct xrdp_mod* v, int rdpindex, int (*server_create_os_surface)(struct xrdp_mod* v, int rdpindex,
int width, int height); int width, int height);
int (*server_switch_os_surface)(struct xrdp_mod* v, int rdpindex); int (*server_switch_os_surface)(struct xrdp_mod* v, int rdpindex);
@ -93,7 +95,29 @@ struct xrdp_mod
int cx, int cy, int cx, int cy,
int rdpindex, int srcx, int srcy); int rdpindex, int srcx, int srcy);
int (*server_set_hints)(struct xrdp_mod* mod, int hints, int mask); int (*server_set_hints)(struct xrdp_mod* mod, int hints, int mask);
long server_dumby[100 - 30]; /* align, 100 minus the number of server /* rail */
int (*server_window_new_update)(struct xrdp_mod* mod, int window_id,
struct rail_window_state_order* window_state,
int flags);
int (*server_window_delete)(struct xrdp_mod* mod, int window_id);
int (*server_window_icon)(struct xrdp_mod* mod,
int window_id, int cache_entry, int cache_id,
struct rail_icon_info* icon_info,
int flags);
int (*server_window_cached_icon)(struct xrdp_mod* mod,
int window_id, int cache_entry,
int cache_id, int flags);
int (*server_notify_new_update)(struct xrdp_mod* mod,
int window_id, int notify_id,
struct rail_notify_state_order* notify_state,
int flags);
int (*server_notify_delete)(struct xrdp_mod* mod, int window_id,
int notify_id);
int (*server_monitored_desktop)(struct xrdp_mod* mod,
struct rail_monitored_desktop_order* mdo,
int flags);
long server_dumby[100 - 37]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
long handle; /* pointer to self as int */ long handle; /* pointer to self as int */

Loading…
Cancel
Save