summaryrefslogtreecommitdiffstats
path: root/libxrdp
diff options
context:
space:
mode:
Diffstat (limited to 'libxrdp')
-rw-r--r--libxrdp/xrdp_fastpath.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c
new file mode 100644
index 00000000..5ce07861
--- /dev/null
+++ b/libxrdp/xrdp_fastpath.c
@@ -0,0 +1,196 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Jay Sorg 2012
+ * Copyright (C) Kevin Zhou 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.
+ */
+
+#include "libxrdp.h"
+
+/*****************************************************************************/
+struct xrdp_fastpath* APP_CC
+xrdp_fastpath_create(struct xrdp_session* session)
+{
+ struct xrdp_fastpath* self;
+
+ self = (struct xrdp_fastpath*)g_malloc(sizeof(struct xrdp_fastpath), 1);
+ self->tcp_layer =
+ ((struct xrdp_rdp*)session->rdp)->sec_layer->
+ mcs_layer->iso_layer->tcp_layer;
+ make_stream(self->out_s);
+ init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE);
+ return self;
+}
+
+/*****************************************************************************/
+void APP_CC
+xrdp_fastpath_delete(struct xrdp_fastpath* self)
+{
+ if (self == 0)
+ {
+ return;
+ }
+ free_stream(self->out_s);
+ g_free(self);
+}
+
+/*****************************************************************************/
+/* returns error */
+int APP_CC
+xrdp_fastpath_reset(struct xrdp_fastpath* self)
+{
+ return 0;
+}
+
+int APP_CC
+xrdp_fastpath_init(struct xrdp_fastpath* self)
+{
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_fastpath_send_update_pdu(struct xrdp_fastpath* self, tui8 updateCode,
+ struct stream* s)
+{
+ tui16 len;
+ tui16 maxLen;
+ tui32 payloadLeft;
+ tui8 fragment;
+ struct stream* s_send;
+ int compression;
+ int i;
+ int i32;
+
+ compression = 0;
+ s_send = self->out_s;
+ maxLen = FASTPATH_MAX_PACKET_SIZE - 6 ; /* 6 bytes for header */
+ payloadLeft = (s->end - s->data);
+ for (i = 0; payloadLeft > 0; i++)
+ {
+ if (payloadLeft > maxLen)
+ {
+ len = maxLen;
+ }
+ else
+ {
+ len = payloadLeft;
+ }
+ payloadLeft -= len;
+ if (payloadLeft == 0)
+ {
+ fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE;
+ }
+ else
+ {
+ fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST;
+ }
+ init_stream(s_send, 0);
+ out_uint8(s_send, 0); /* fOutputHeader */
+ i32 = ((len + 6) >> 8) | 0x80;
+ out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */
+ i32 = (len + 6) & 0xff;
+ out_uint8(s_send, i32);
+ i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) |
+ ((compression & 0x03) << 6);
+ out_uint8(s_send, i32);
+ out_uint16_le(s_send, len);
+ s_copy(s_send, s, len);
+ s_mark_end(s_send);
+ if (xrdp_tcp_send(self->tcp_layer, s_send) != 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int
+xrdp_fastpath_process_update(struct xrdp_fastpath* self, tui8 updateCode,
+ tui32 size, struct stream* s)
+{
+ switch (updateCode)
+ {
+ case FASTPATH_UPDATETYPE_ORDERS:
+ case FASTPATH_UPDATETYPE_BITMAP:
+ case FASTPATH_UPDATETYPE_PALETTE:
+ case FASTPATH_UPDATETYPE_SYNCHRONIZE:
+ case FASTPATH_UPDATETYPE_SURFCMDS:
+ case FASTPATH_UPDATETYPE_PTR_NULL:
+ case FASTPATH_UPDATETYPE_PTR_DEFAULT:
+ case FASTPATH_UPDATETYPE_PTR_POSITION:
+ case FASTPATH_UPDATETYPE_COLOR:
+ case FASTPATH_UPDATETYPE_CACHED:
+ case FASTPATH_UPDATETYPE_POINTER:
+ break;
+ default:
+ g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X",
+ updateCode);
+ break;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+int APP_CC
+xrdp_fastpath_process_data(struct xrdp_fastpath* self, struct stream* s,
+ tui8 header)
+{
+ tui8 encryptionFlags;
+ tui8 numberEvents;
+ tui8 length2;
+ tui8 updateHeader;
+ tui8 updateCode;
+ tui8 updateFrag;
+ tui8 updateComp;
+ tui16 length;
+ tui32 size;
+
+ encryptionFlags = (header & 0xc0) >> 6;
+ numberEvents = (header & 0x3c) >> 2;
+ xrdp_tcp_recv(self->tcp_layer, s, 1);
+ in_uint8(s, length);
+ if (length & 0x80)
+ {
+ xrdp_tcp_recv(self->tcp_layer, s, 1);
+ in_uint8(s, length2);
+ length = (length & 0x7f) << 8 + length2 - 3;
+ }
+ else
+ {
+ length -= 2;
+ }
+ xrdp_tcp_recv(self->tcp_layer, s, length);
+ if (encryptionFlags != 0)
+ {
+ /* TODO decryption ...*/
+ }
+ /* parse updateHeader */
+ in_uint8(s, updateHeader);
+ updateCode = (updateHeader & 0x0f);
+ updateFrag = (updateHeader & 0x30) >> 4;
+ updateComp = (updateHeader & 0xc0) >> 6;
+ if (updateFrag && updateComp)
+ {
+ /* TODO */
+ g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d",
+ updateFrag,updateComp);
+ return 1;
+ }
+ in_uint16_le(s, size);
+ return xrdp_fastpath_process_update(self, updateCode, size, s);
+}