summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
authorjsorg71 <jsorg71>2005-08-24 01:09:33 +0000
committerjsorg71 <jsorg71>2005-08-24 01:09:33 +0000
commit7d891a1bde2f8287f333fda9acc88310d783da73 (patch)
tree5202a565b2bee120ed075a0cac95221b3f1e0427 /libxrdp
parent1881c8b1b847ef0de1c42f635ee9e10b99b5863e (diff)
downloadxrdp-proprietary-7d891a1bde2f8287f333fda9acc88310d783da73.tar.gz
xrdp-proprietary-7d891a1bde2f8287f333fda9acc88310d783da73.zip
added server_reset(which uses demand_active) for resizing the rdp client
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/libxrdp.c68
-rw-r--r--libxrdp/libxrdp.h4
-rw-r--r--libxrdp/libxrdpinc.h4
-rw-r--r--libxrdp/xrdp_orders.c35
-rw-r--r--libxrdp/xrdp_rdp.c45
5 files changed, 138 insertions, 18 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c
index 5a8f3837..c7af956e 100644
--- a/libxrdp/libxrdp.c
+++ b/libxrdp/libxrdp.c
@@ -33,6 +33,8 @@ libxrdp_init(long id, int sck)
session->rdp = xrdp_rdp_create(session, sck);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp*)session->rdp);
session->client_info = &(((struct xrdp_rdp*)session->rdp)->client_info);
+ make_stream(session->s);
+ init_stream(session->s, 8192 * 2);
return session;
}
@@ -46,6 +48,7 @@ libxrdp_exit(struct xrdp_session* session)
}
xrdp_orders_delete((struct xrdp_orders*)session->orders);
xrdp_rdp_delete((struct xrdp_rdp*)session->rdp);
+ free_stream(session->s);
g_free(session);
return 0;
}
@@ -68,19 +71,16 @@ libxrdp_process_incomming(struct xrdp_session* session)
int EXPORT_CC
libxrdp_process_data(struct xrdp_session* session)
{
- struct stream* s;
int cont;
int rv;
int code;
cont = 1;
rv = 0;
- make_stream(s);
- init_stream(s, 8192);
- while (cont && !session->term)
+ while ((cont || !session->up_and_running) && !session->term)
{
code = 0;
- if (xrdp_rdp_recv((struct xrdp_rdp*)session->rdp, s, &code) != 0)
+ if (xrdp_rdp_recv((struct xrdp_rdp*)session->rdp, session->s, &code) != 0)
{
rv = 1;
break;
@@ -90,14 +90,17 @@ libxrdp_process_data(struct xrdp_session* session)
{
case -1:
xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp);
+ session->up_and_running = 0;
break;
case 0:
break;
case RDP_PDU_CONFIRM_ACTIVE: /* 3 */
- xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp, s);
+ xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp,
+ session->s);
break;
case RDP_PDU_DATA: /* 7 */
- if (xrdp_rdp_process_data((struct xrdp_rdp*)session->rdp, s) != 0)
+ if (xrdp_rdp_process_data((struct xrdp_rdp*)session->rdp,
+ session->s) != 0)
{
DEBUG(("libxrdp_process_data returned non zero\n\r"));
cont = 0;
@@ -110,10 +113,9 @@ libxrdp_process_data(struct xrdp_session* session)
}
if (cont)
{
- cont = s->next_packet < s->end;
+ cont = session->s->next_packet < session->s->end;
}
}
- free_stream(s);
return rv;
}
@@ -528,3 +530,51 @@ libxrdp_orders_send_font(struct xrdp_session* session,
return xrdp_orders_send_font((struct xrdp_orders*)session->orders,
font_char, font_index, char_index);
}
+
+/*****************************************************************************/
+int EXPORT_CC
+libxrdp_reset(struct xrdp_session* session,
+ int width, int height, int bpp)
+{
+ if (session->client_info != 0)
+ {
+ /* older client can't resize */
+ if (session->client_info->build <= 419)
+ {
+ return 0;
+ }
+ /* if same, don't need to do anything */
+ if (session->client_info->width == width &&
+ session->client_info->height == height &&
+ session->client_info->bpp == bpp)
+ {
+ return 0;
+ }
+ session->client_info->width = width;
+ session->client_info->height = height;
+ session->client_info->bpp = bpp;
+ }
+ else
+ {
+ return 1;
+ }
+ /* this will send any lingering orders */
+ if (xrdp_orders_reset((struct xrdp_orders*)session->orders) != 0)
+ {
+ return 1;
+ }
+ /* shut down the rdp client */
+ if (xrdp_rdp_send_deactive((struct xrdp_rdp*)session->rdp) != 0)
+ {
+ return 1;
+ }
+ /* this should do the resizing */
+ if (xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp) != 0)
+ {
+ return 1;
+ }
+ /* process till up and running */
+ session->up_and_running = 0;
+ libxrdp_process_data(session);
+ return 0;
+}
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h
index 29c2bdb6..67f325e4 100644
--- a/libxrdp/libxrdp.h
+++ b/libxrdp/libxrdp.h
@@ -266,6 +266,8 @@ int APP_CC
xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s);
int APP_CC
xrdp_rdp_disconnect(struct xrdp_rdp* self);
+int APP_CC
+xrdp_rdp_send_deactive(struct xrdp_rdp* self);
/* xrdp_orders.c */
struct xrdp_orders* APP_CC
@@ -274,6 +276,8 @@ xrdp_orders_create(struct xrdp_session* session,
void APP_CC
xrdp_orders_delete(struct xrdp_orders* self);
int APP_CC
+xrdp_orders_reset(struct xrdp_orders* self);
+int APP_CC
xrdp_orders_init(struct xrdp_orders* self);
int APP_CC
xrdp_orders_send(struct xrdp_orders* self);
diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h
index 626b7bbd..68a1873e 100644
--- a/libxrdp/libxrdpinc.h
+++ b/libxrdp/libxrdpinc.h
@@ -90,6 +90,7 @@ struct xrdp_session
void* orders;
struct xrdp_client_info* client_info;
int up_and_running;
+ struct stream* s;
};
struct xrdp_session* DEFAULT_CC
@@ -170,5 +171,8 @@ int DEFAULT_CC
libxrdp_orders_send_font(struct xrdp_session* session,
struct xrdp_font_char* font_char,
int font_index, int char_index);
+int DEFAULT_CC
+libxrdp_reset(struct xrdp_session* session,
+ int width, int height, int bpp);
#endif
diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c
index c81899d2..6289858f 100644
--- a/libxrdp/xrdp_orders.c
+++ b/libxrdp/xrdp_orders.c
@@ -51,6 +51,38 @@ xrdp_orders_delete(struct xrdp_orders* self)
}
/*****************************************************************************/
+/* set all values to zero */
+/* returns error */
+int APP_CC
+xrdp_orders_reset(struct xrdp_orders* self)
+{
+ struct stream* out_s;
+ struct xrdp_rdp* rdp_layer;
+ struct xrdp_session* session;
+ struct xrdp_wm* wm;
+
+ if (xrdp_orders_force_send(self) != 0)
+ {
+ return 1;
+ }
+ /* save these */
+ out_s = self->out_s;
+ rdp_layer = self->rdp_layer;
+ session = self->session;
+ wm = self->wm;
+ /* set whole struct to zero */
+ g_memset(self, 0, sizeof(struct xrdp_orders));
+ /* set some stuff back */
+ self->out_s = out_s;
+ self->rdp_layer = rdp_layer;
+ self->session = session;
+ self->wm = wm;
+ self->clip_right = 1; /* silly rdp right clip */
+ self->clip_bottom = 1; /* silly rdp bottom clip */
+ return 0;
+}
+
+/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_orders_init(struct xrdp_orders* self)
@@ -90,6 +122,7 @@ xrdp_orders_send(struct xrdp_orders* self)
DEBUG(("xrdp_orders_send sending %d orders\n\r", self->order_count));
self->order_count_ptr[0] = self->order_count;
self->order_count_ptr[1] = self->order_count >> 8;
+ self->order_count = 0;
if (xrdp_rdp_send_data(self->rdp_layer, self->out_s,
RDP_DATA_PDU_UPDATE) != 0)
{
@@ -105,7 +138,7 @@ xrdp_orders_send(struct xrdp_orders* self)
int APP_CC
xrdp_orders_force_send(struct xrdp_orders* self)
{
- if (self->order_count > 0)
+ if (self->order_count > 0 && self->order_count > 0)
{
s_mark_end(self->out_s);
DEBUG(("xrdp_orders_force_send sending %d orders\n\r", self->order_count));
diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c
index a9256cbf..8a883f56 100644
--- a/libxrdp/xrdp_rdp.c
+++ b/libxrdp/xrdp_rdp.c
@@ -321,12 +321,17 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
}
out_uint32_le(s, self->share_id);
- out_uint32_be(s, 0x04000401);
- out_uint32_be(s, 0x524e5300);
- out_uint32_be(s, 0x08000000);
- out_uint32_be(s, 0x09000800);
+
+ out_uint16_le(s, 4); /* 4 chars for RDP\0 */
+ out_uint16_le(s, 0x0104); /* size after num caps */
+ out_uint8a(s, "RDP", 4);
+ out_uint32_le(s, 8); /* num caps 8 */
+
+ /* Output share capability set */
+ out_uint16_le(s, RDP_CAPSET_SHARE);
+ out_uint16_le(s, RDP_CAPLEN_SHARE);
out_uint16_le(s, self->mcs_channel);
- out_uint16_be(s, 0xb5e2);
+ out_uint16_be(s, 0xb5e2); /* 0x73e1 */
/* Output general capability set */
out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */
@@ -336,7 +341,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
out_uint16_le(s, 0x200); /* Protocol version */
out_uint16_le(s, 0); /* pad */
out_uint16_le(s, 0); /* Compression types */
- out_uint16_le(s, 0); /* pad */
+ out_uint16_le(s, 0); /* pad use 0x40d for rdp packets */
out_uint16_le(s, 0); /* Update capability */
out_uint16_le(s, 0); /* Remote unshare capability */
out_uint16_le(s, 0); /* Compression level */
@@ -407,9 +412,10 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self)
out_uint8(s, 0);
out_uint8(s, 0);
out_uint16_le(s, 0x6a1);
- out_uint8s(s, 6); /* ? */
+ out_uint8s(s, 2); /* ? */
out_uint32_le(s, 0x0f4240); /* desk save */
- out_uint32_le(s, 0); /* ? */
+ out_uint32_le(s, 0x0f4240); /* desk save */
+ out_uint32_le(s, 1); /* ? */
out_uint32_le(s, 0); /* ? */
/* Output color cache capability set */
@@ -849,3 +855,26 @@ xrdp_rdp_disconnect(struct xrdp_rdp* self)
{
return xrdp_sec_disconnect(self->sec_layer);
}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_rdp_send_deactive(struct xrdp_rdp* self)
+{
+ struct stream* s;
+
+ make_stream(s);
+ init_stream(s, 8192);
+ if (xrdp_rdp_init(self, s) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ s_mark_end(s);
+ if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0)
+ {
+ free_stream(s);
+ return 1;
+ }
+ free_stream(s);
+ return 0;
+}