channel encomsp hardend
authorMartin Haimberger <martin.haimberger@thincast.com>
Mon, 8 Jun 2015 12:44:10 +0000 (05:44 -0700)
committerMartin Haimberger <martin.haimberger@thincast.com>
Thu, 18 Jun 2015 10:04:32 +0000 (03:04 -0700)
channels/encomsp/client/encomsp_main.c
channels/encomsp/client/encomsp_main.h
channels/encomsp/server/encomsp_main.c
client/X11/xf_client.c
include/freerdp/client/encomsp.h
include/freerdp/server/encomsp.h
server/shadow/shadow_encomsp.c

index 9e93348..36648e3 100644 (file)
@@ -3,6 +3,8 @@
  * Multiparty Virtual Channel
  *
  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #include "encomsp_main.h"
 
-static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */
        Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */
 
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
-static int encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_write_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        Stream_Write_UINT16(s, header->Type); /* Type (2 bytes) */
        Stream_Write_UINT16(s, header->Length); /* Length (2 bytes) */
 
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
-static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
+static WIN32ERROR encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
 {
        ZeroMemory(str, sizeof(ENCOMSP_UNICODE_STRING));
 
        if (Stream_GetRemainingLength(s) < 2)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, str->cchString); /* cchString (2 bytes) */
 
        if (str->cchString > 1024)
-               return -1;
+       {
+               WLog_ERR(TAG, "cchString was %d but has to be < 1025!", str->cchString);
+               return ERROR_INVALID_DATA;
+       }
 
        if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2))
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */
 
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
 EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp)
@@ -75,12 +89,12 @@ EncomspClientContext* encomsp_get_client_interface(encomspPlugin* encomsp)
        return pInterface;
 }
 
-int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
+WIN32ERROR encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
 {
-       UINT32 status = 0;
+       WIN32ERROR status;
 
        if (!encomsp)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
 #if 0
        WLog_INFO(TAG, "EncomspWrite (%d)", Stream_Length(s));
@@ -91,333 +105,407 @@ int encomsp_virtual_channel_write(encomspPlugin* encomsp, wStream* s)
                        Stream_Buffer(s), (UINT32) Stream_Length(s), s);
 
        if (status != CHANNEL_RC_OK)
-       {
                WLog_ERR(TAG,  "VirtualChannelWrite failed with %s [%08X]",
                                 WTSErrorToString(status), status);
-               return -1;
-       }
 
-       return 1;
+       return status;
 }
 
-static int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_FILTER_UPDATED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 1)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT8(s, pdu.Flags); /* Flags (1 byte) */
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->FilterUpdated)
-       {
-               return context->FilterUpdated(context, &pdu);
-       }
+       IFCALLRET(context->FilterUpdated, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->FilterUpdated failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_APPLICATION_CREATED_PDU pdu;
+       WIN32ERROR error;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 6)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
        Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */
 
-       if (encomsp_read_unicode_string(s, &(pdu.Name)) < 0)
-               return -1;
+       if ((error = encomsp_read_unicode_string(s, &(pdu.Name)) ))
+       {
+               WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error);
+               return error;
+       }
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ApplicationCreated)
-       {
-               return context->ApplicationCreated(context, &pdu);
-       }
+       IFCALLRET(context->ApplicationCreated, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ApplicationCreated failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_APPLICATION_REMOVED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ApplicationRemoved)
-       {
-               return context->ApplicationRemoved(context, &pdu);
-       }
+       IFCALLRET(context->ApplicationRemoved, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ApplicationRemoved failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_WINDOW_CREATED_PDU pdu;
+       WIN32ERROR error;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 10)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
        Stream_Read_UINT32(s, pdu.AppId); /* AppId (4 bytes) */
        Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */
 
-       if (encomsp_read_unicode_string(s, &(pdu.Name)) < 0)
-               return -1;
+       if ((error = encomsp_read_unicode_string(s, &(pdu.Name))))
+       {
+               WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error);
+               return error;
+       }
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->WindowCreated)
-       {
-               return context->WindowCreated(context, &pdu);
-       }
+       IFCALLRET(context->WindowCreated, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->WindowCreated failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_WINDOW_REMOVED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->WindowRemoved)
-       {
-               return context->WindowRemoved(context, &pdu);
-       }
+       IFCALLRET(context->WindowRemoved, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->WindowRemoved failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_SHOW_WINDOW_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 4)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.WndId); /* WndId (4 bytes) */
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ShowWindow)
-       {
-               return context->ShowWindow(context, &pdu);
-       }
+       IFCALLRET(context->ShowWindow, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ShowWindow failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_PARTICIPANT_CREATED_PDU pdu;
+       WIN32ERROR error;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 10)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
        Stream_Read_UINT32(s, pdu.GroupId); /* GroupId (4 bytes) */
        Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
 
-       if (encomsp_read_unicode_string(s, &(pdu.FriendlyName)) < 0)
-               return -1;
+
+       if ((error = encomsp_read_unicode_string(s, &(pdu.FriendlyName))))
+       {
+               WLog_ERR(TAG, "encomsp_read_unicode_string failed with error %lu", error);
+               return error;
+       }
 
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ParticipantCreated)
-       {
-               return context->ParticipantCreated(context, &pdu);
-       }
+       IFCALLRET(context->ParticipantCreated, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ParticipantCreated failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_PARTICIPANT_REMOVED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 12)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
        Stream_Read_UINT32(s, pdu.DiscType); /* DiscType (4 bytes) */
@@ -426,41 +514,50 @@ static int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream*
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ParticipantRemoved)
-       {
-               return context->ParticipantRemoved(context, &pdu);
-       }
+       IFCALLRET(context->ParticipantRemoved, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ParticipantRemoved failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 6)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
        Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
@@ -468,28 +565,34 @@ static int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enco
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ChangeParticipantControlLevel)
-       {
-               return context->ChangeParticipantControlLevel(context, &pdu);
-       }
+       IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
+static WIN32ERROR encomsp_send_change_participant_control_level_pdu(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
 {
        wStream* s;
        encomspPlugin* encomsp;
+       WIN32ERROR error;
 
        encomsp = (encomspPlugin*) context->handle;
 
@@ -497,29 +600,37 @@ static int encomsp_send_change_participant_control_level_pdu(EncomspClientContex
        pdu->Length = ENCOMSP_ORDER_HEADER_SIZE + 6;
 
        s = Stream_New(NULL, pdu->Length);
+       if (!s)
+       {
+               WLog_ERR(TAG, "Stream_New failed!");
+               return CHANNEL_RC_NO_MEMORY;
+       }
 
-       encomsp_write_header(s, (ENCOMSP_ORDER_HEADER*) pdu);
+       if ((error = encomsp_write_header(s, (ENCOMSP_ORDER_HEADER*) pdu)))
+       {
+               WLog_ERR(TAG, "encomsp_write_header failed with error %lu!", error);
+               return error;
+       }
 
        Stream_Write_UINT16(s, pdu->Flags); /* Flags (2 bytes) */
        Stream_Write_UINT32(s, pdu->ParticipantId); /* ParticipantId (4 bytes) */
 
        Stream_SealLength(s);
 
-       encomsp_virtual_channel_write(encomsp, s);
-
-       return 1;
+       return encomsp_virtual_channel_write(encomsp, s);
 }
 
-static int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
@@ -528,34 +639,40 @@ static int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStre
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->GraphicsStreamPaused)
-       {
-               return context->GraphicsStreamPaused(context, &pdu);
-       }
+       IFCALLRET(context->GraphicsStreamPaused, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->GraphicsStreamPaused failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        EncomspClientContext* context;
        ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = encomsp_get_client_interface(encomsp);
 
        if (!context)
-               return -1;
+               return ERROR_INVALID_HANDLE;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
@@ -564,92 +681,142 @@ static int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStr
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->GraphicsStreamResumed)
-       {
-               return context->GraphicsStreamResumed(context, &pdu);
-       }
+       IFCALLRET(context->GraphicsStreamResumed, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->GraphicsStreamResumed failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_process_receive(encomspPlugin* encomsp, wStream* s)
+static WIN32ERROR encomsp_process_receive(encomspPlugin* encomsp, wStream* s)
 {
-       int status = 1;
+       WIN32ERROR error = CHANNEL_RC_OK;
        ENCOMSP_ORDER_HEADER header;
 
        while (Stream_GetRemainingLength(s) > 0)
        {
-               if (encomsp_read_header(s, &header) < 0)
-                       return -1;
+               if ((error = encomsp_read_header(s, &header)))
+               {
+                       WLog_ERR(TAG, "encomsp_read_header failed with error %lu!", error);
+                       return error;
+               }
 
                //WLog_DBG(TAG, "EncomspReceive: Type: %d Length: %d", header.Type, header.Length);
 
                switch (header.Type)
                {
                        case ODTYPE_FILTER_STATE_UPDATED:
-                               status = encomsp_recv_filter_updated_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_filter_updated_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_filter_updated_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_APP_REMOVED:
-                               status = encomsp_recv_application_removed_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_application_removed_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_APP_CREATED:
-                               status = encomsp_recv_application_created_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_application_created_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_application_removed_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_WND_REMOVED:
-                               status = encomsp_recv_window_removed_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_window_removed_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_window_removed_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_WND_CREATED:
-                               status = encomsp_recv_window_created_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_window_created_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_window_created_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_WND_SHOW:
-                               status = encomsp_recv_show_window_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_show_window_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_show_window_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_PARTICIPANT_REMOVED:
-                               status = encomsp_recv_participant_removed_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_participant_removed_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_participant_removed_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_PARTICIPANT_CREATED:
-                               status = encomsp_recv_participant_created_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_participant_created_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_participant_created_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_PARTICIPANT_CTRL_CHANGED:
-                               status = encomsp_recv_change_participant_control_level_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_change_participant_control_level_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_GRAPHICS_STREAM_PAUSED:
-                               status = encomsp_recv_graphics_stream_paused_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_graphics_stream_paused_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_graphics_stream_paused_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        case ODTYPE_GRAPHICS_STREAM_RESUMED:
-                               status = encomsp_recv_graphics_stream_resumed_pdu(encomsp, s, &header);
+                               if ((error = encomsp_recv_graphics_stream_resumed_pdu(encomsp, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_graphics_stream_resumed_pdu failed with error %lu!", error);
+                                       return error;
+                               }
                                break;
 
                        default:
-                               status = -1;
+                               WLog_ERR(TAG, "header.Type %d not found", header.Type);
+                               return ERROR_INVALID_DATA;
                                break;
                }
 
-               if (status < 0)
-                       return -1;
        }
-
-       return status;
+       return error;
 }
 
 static void encomsp_process_connect(encomspPlugin* encomsp)
@@ -662,16 +829,24 @@ static void encomsp_process_connect(encomspPlugin* encomsp)
 static wListDictionary* g_InitHandles = NULL;
 static wListDictionary* g_OpenHandles = NULL;
 
-BOOL encomsp_add_init_handle_data(void* pInitHandle, void* pUserData)
+WIN32ERROR encomsp_add_init_handle_data(void* pInitHandle, void* pUserData)
 {
        if (!g_InitHandles)
        {
                g_InitHandles = ListDictionary_New(TRUE);
-               if (!g_InitHandles)
-                       return FALSE;
+       }
+       if (!g_InitHandles)
+       {
+               WLog_ERR(TAG, "ListDictionary_New failed!");
+               return CHANNEL_RC_NO_MEMORY;
        }
 
-       return ListDictionary_Add(g_InitHandles, pInitHandle, pUserData);
+       if (!ListDictionary_Add(g_InitHandles, pInitHandle, pUserData))
+       {
+               WLog_ERR(TAG, "ListDictionary_Add failed!");
+               return ERROR_INTERNAL_ERROR;
+       }
+       return CHANNEL_RC_OK;
 }
 
 void* encomsp_get_init_handle_data(void* pInitHandle)
@@ -691,18 +866,27 @@ void encomsp_remove_init_handle_data(void* pInitHandle)
        }
 }
 
-BOOL encomsp_add_open_handle_data(DWORD openHandle, void* pUserData)
+WIN32ERROR encomsp_add_open_handle_data(DWORD openHandle, void* pUserData)
 {
        void* pOpenHandle = (void*) (size_t) openHandle;
 
        if (!g_OpenHandles)
        {
                g_OpenHandles = ListDictionary_New(TRUE);
-               if (!g_OpenHandles)
-                       return FALSE;
        }
 
-       return ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData);
+       if (!g_OpenHandles)
+       {
+               WLog_ERR(TAG, "ListDictionary_New failed!");
+               return CHANNEL_RC_NO_MEMORY;
+       }
+
+       if (!ListDictionary_Add(g_OpenHandles, pOpenHandle, pUserData))
+       {
+               WLog_ERR(TAG, "ListDictionary_Add failed!");
+               return ERROR_INTERNAL_ERROR;
+       }
+       return CHANNEL_RC_OK;
 }
 
 void* encomsp_get_open_handle_data(DWORD openHandle)
@@ -749,15 +933,13 @@ int encomsp_send(encomspPlugin* encomsp, wStream* s)
        return status;
 }
 
-static void encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
+static WIN32ERROR encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
                void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
 {
        wStream* data_in;
 
        if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
-       {
-               return;
-       }
+               return CHANNEL_RC_OK;
 
        if (dataFlags & CHANNEL_FLAG_FIRST)
        {
@@ -765,10 +947,19 @@ static void encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
                        Stream_Free(encomsp->data_in, TRUE);
 
                encomsp->data_in = Stream_New(NULL, totalLength);
+               if (!encomsp->data_in)
+               {
+                       WLog_ERR(TAG, "Stream_New failed!");
+                       return CHANNEL_RC_NO_MEMORY;
+               }
        }
 
        data_in = encomsp->data_in;
-       Stream_EnsureRemainingCapacity(data_in, (int) dataLength);
+       if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
+       {
+               WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
+               return ERROR_INTERNAL_ERROR;
+       }
        Stream_Write(data_in, pData, dataLength);
 
        if (dataFlags & CHANNEL_FLAG_LAST)
@@ -776,6 +967,7 @@ static void encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
                if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
                {
                        WLog_ERR(TAG,  "encomsp_plugin_process_received: read error");
+                       return ERROR_INVALID_DATA;
                }
 
                encomsp->data_in = NULL;
@@ -784,6 +976,7 @@ static void encomsp_virtual_channel_event_data_received(encomspPlugin* encomsp,
 
                MessageQueue_Post(encomsp->queue, NULL, 0, (void*) data_in, NULL);
        }
+       return CHANNEL_RC_OK;
 }
 
 static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT event,
@@ -796,13 +989,20 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT
        if (!encomsp)
        {
                WLog_ERR(TAG,  "encomsp_virtual_channel_open_event: error no match");
+               encomsp->error = CHANNEL_RC_BAD_CHANNEL;
                return;
        }
 
+       encomsp->error = CHANNEL_RC_OK;
+
        switch (event)
        {
                case CHANNEL_EVENT_DATA_RECEIVED:
-                       encomsp_virtual_channel_event_data_received(encomsp, pData, dataLength, totalLength, dataFlags);
+                       if ((encomsp->error = encomsp_virtual_channel_event_data_received(encomsp, pData, dataLength, totalLength, dataFlags)))
+                       {
+                               WLog_ERR(TAG,  "encomsp_virtual_channel_event_data_received failed with error %lu", encomsp->error);
+                               return;
+                       }
                        break;
 
                case CHANNEL_EVENT_WRITE_COMPLETE:
@@ -812,6 +1012,8 @@ static VOID VCAPITYPE encomsp_virtual_channel_open_event(DWORD openHandle, UINT
                case CHANNEL_EVENT_USER:
                        break;
        }
+       return;
+       //TODO erport error
 }
 
 static void* encomsp_virtual_channel_client_thread(void* arg)
@@ -819,6 +1021,7 @@ static void* encomsp_virtual_channel_client_thread(void* arg)
        wStream* data;
        wMessage message;
        encomspPlugin* encomsp = (encomspPlugin*) arg;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        encomsp_process_connect(encomsp);
 
@@ -835,53 +1038,58 @@ static void* encomsp_virtual_channel_client_thread(void* arg)
                        if (message.id == 0)
                        {
                                data = (wStream*) message.wParam;
-                               encomsp_process_receive(encomsp, data);
+                               if ((error = encomsp_process_receive(encomsp, data)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error);
+                                       break;
+                               }
                        }
                }
        }
 
-       ExitThread(0);
+       ExitThread((DWORD)error);
        return NULL;
 }
 
-static void encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVOID pData, UINT32 dataLength)
+static WIN32ERROR encomsp_virtual_channel_event_connected(encomspPlugin* encomsp, LPVOID pData, UINT32 dataLength)
 {
        UINT32 status;
+       WIN32ERROR error;
 
        status = encomsp->channelEntryPoints.pVirtualChannelOpen(encomsp->InitHandle,
                &encomsp->OpenHandle, encomsp->channelDef.name, encomsp_virtual_channel_open_event);
 
-       if (!encomsp_add_open_handle_data(encomsp->OpenHandle, encomsp))
+       if (status != CHANNEL_RC_OK)
        {
-               WLog_ERR(TAG, "%s: unable to register open handle", __FUNCTION__);
-               return;
+               WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
+                                WTSErrorToString(status), status);
+               return status;
        }
 
-       if (status != CHANNEL_RC_OK)
+       if ((error = encomsp_add_open_handle_data(encomsp->OpenHandle, encomsp)))
        {
-               WLog_ERR(TAG,  "pVirtualChannelOpen failed with %s [%08X]",
-                                WTSErrorToString(status), status);
-               return;
+               WLog_ERR(TAG, "encomsp_process_receive failed with error %lu!", error);
+               return status;
        }
 
        encomsp->queue = MessageQueue_New(NULL);
        if (!encomsp->queue)
        {
-               WLog_ERR(TAG, "%s: unable to create message queue", __FUNCTION__);
-               return;
+               WLog_ERR(TAG, "MessageQueue_New failed!");
+               return CHANNEL_RC_NO_MEMORY;
        }
 
-       encomsp->thread = CreateThread(NULL, 0,
-                       (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, 0, NULL);
-       if (!encomsp->thread)
+       if (!(encomsp->thread = CreateThread(NULL, 0,
+                       (LPTHREAD_START_ROUTINE) encomsp_virtual_channel_client_thread, (void*) encomsp, 0, NULL)))
        {
-               WLog_ERR(TAG, "%s: unable to create thread", __FUNCTION__);
-               return;
+               WLog_ERR(TAG, "CreateThread failed!");
+               MessageQueue_Free(encomsp->queue);
+               return ERROR_INTERNAL_ERROR;
        }
-
+       return CHANNEL_RC_OK;
 }
 
-static void encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
+static WIN32ERROR encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
 {
        UINT rc;
        MessageQueue_PostQuit(encomsp->queue, 0);
@@ -898,6 +1106,7 @@ static void encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
        {
                WLog_ERR(TAG, "pVirtualChannelClose failed with %s [%08X]",
                                 WTSErrorToString(rc), rc);
+               return rc;
        }
 
        if (encomsp->data_in)
@@ -907,16 +1116,18 @@ static void encomsp_virtual_channel_event_disconnected(encomspPlugin* encomsp)
        }
 
        encomsp_remove_open_handle_data(encomsp->OpenHandle);
+       return CHANNEL_RC_OK;
 }
 
 
-static void encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp)
+static WIN32ERROR encomsp_virtual_channel_event_terminated(encomspPlugin* encomsp)
 {
        encomsp_remove_init_handle_data(encomsp->InitHandle);
        free(encomsp);
+       return CHANNEL_RC_OK;
 }
 
-static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
+static void VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, UINT event, LPVOID pData, UINT dataLength)
 {
        encomspPlugin* encomsp;
 
@@ -925,23 +1136,40 @@ static VOID VCAPITYPE encomsp_virtual_channel_init_event(LPVOID pInitHandle, UIN
        if (!encomsp)
        {
                WLog_ERR(TAG,  "encomsp_virtual_channel_init_event: error no match");
+               encomsp->error = CHANNEL_RC_BAD_CHANNEL;
                return;
        }
 
+       encomsp->error = CHANNEL_RC_OK;
+
        switch (event)
        {
                case CHANNEL_EVENT_CONNECTED:
-                       encomsp_virtual_channel_event_connected(encomsp, pData, dataLength);
+                       if ((encomsp->error = encomsp_virtual_channel_event_connected(encomsp, pData, dataLength)))
+                       {
+                               WLog_ERR(TAG, "encomsp_virtual_channel_event_connected failed with error %lu", encomsp->error);
+                               return;
+                       }
                        break;
 
                case CHANNEL_EVENT_DISCONNECTED:
-                       encomsp_virtual_channel_event_disconnected(encomsp);
+                       if ((encomsp->error = encomsp_virtual_channel_event_disconnected(encomsp)))
+                       {
+                               WLog_ERR(TAG, "encomsp_virtual_channel_event_disconnected failed with error %lu", encomsp->error);
+                               return;
+                       }
                        break;
 
                case CHANNEL_EVENT_TERMINATED:
                        encomsp_virtual_channel_event_terminated(encomsp);
                        break;
+               default:
+                       WLog_ERR(TAG, "uknown event type %d", event);
+                       encomsp->error = ERROR_INVALID_DATA;
+                       return;
        }
+       return;
+       //TODO report error
 }
 
 /* encomsp is always built-in */
@@ -953,8 +1181,14 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
        encomspPlugin* encomsp;
        EncomspClientContext* context;
        CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
+       BOOL isFreerdp = FALSE;
 
        encomsp = (encomspPlugin*) calloc(1, sizeof(encomspPlugin));
+       if (!encomsp)
+       {
+               WLog_ERR(TAG, "calloc failed!");
+               return FALSE;
+       }
 
        encomsp->channelDef.options =
                        CHANNEL_OPTION_INITIALIZED |
@@ -970,6 +1204,11 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
                        (pEntryPointsEx->MagicNumber == FREERDP_CHANNEL_MAGIC_NUMBER))
        {
                context = (EncomspClientContext*) calloc(1, sizeof(EncomspClientContext));
+               if (!context)
+               {
+                       WLog_ERR(TAG, "calloc failed!");
+                       goto error_out;
+               }
 
                context->handle = (void*) encomsp;
 
@@ -987,6 +1226,7 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
 
                *(pEntryPointsEx->ppInterface) = (void*) context;
                encomsp->context = context;
+               isFreerdp = TRUE;
        }
 
        CopyMemory(&(encomsp->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
@@ -997,11 +1237,22 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
        {
                WLog_ERR(TAG, "pVirtualChannelInit failed with %s [%08X]",
                                 WTSErrorToString(rc), rc);
-               free(encomsp);
-               return -1;
+               goto error_out;
        }
+
        encomsp->channelEntryPoints.pInterface = *(encomsp->channelEntryPoints.ppInterface);
        encomsp->channelEntryPoints.ppInterface = &(encomsp->channelEntryPoints.pInterface);
 
-       return encomsp_add_init_handle_data(encomsp->InitHandle, (void*) encomsp);
+       if ((encomsp->error = encomsp_add_init_handle_data(encomsp->InitHandle, (void*) encomsp)))
+       {
+               WLog_ERR(TAG, "encomsp_add_init_handle_data failed with error %lu!", encomsp->error);
+               goto error_out;
+       }
+
+       return TRUE;
+error_out:
+       if (isFreerdp)
+               free(encomsp->context);
+       free(encomsp);
+       return FALSE;
 }
index 444c0bc..5aea1b2 100644 (file)
@@ -3,6 +3,8 @@
  * Multiparty Virtual Channel
  *
  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,6 +49,7 @@ struct encomsp_plugin
        void* InitHandle;
        DWORD OpenHandle;
        wMessageQueue* queue;
+       WIN32ERROR error;
 };
 typedef struct encomsp_plugin encomspPlugin;
 
index b15bff4..6547815 100644 (file)
@@ -3,6 +3,8 @@
  * Multiparty Virtual Channel
  *
  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #define TAG CHANNELS_TAG("encomsp.server")
 
-static int encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_read_header(wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        if (Stream_GetRemainingLength(s) < ENCOMSP_ORDER_HEADER_SIZE)
-               return -1;
+               return ERROR_INVALID_DATA;
 
        Stream_Read_UINT16(s, header->Type); /* Type (2 bytes) */
        Stream_Read_UINT16(s, header->Length); /* Length (2 bytes) */
 
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
 #if 0
@@ -74,17 +76,21 @@ static int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
 
 #endif
 
-static int encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header)
+static WIN32ERROR encomsp_recv_change_participant_control_level_pdu(EncomspServerContext* context, wStream* s, ENCOMSP_ORDER_HEADER* header)
 {
        int beg, end;
        ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU pdu;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        beg = ((int) Stream_GetPosition(s)) - ENCOMSP_ORDER_HEADER_SIZE;
 
        CopyMemory(&pdu, header, sizeof(ENCOMSP_ORDER_HEADER));
 
        if (Stream_GetRemainingLength(s) < 6)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        Stream_Read_UINT16(s, pdu.Flags); /* Flags (2 bytes) */
        Stream_Read_UINT32(s, pdu.ParticipantId); /* ParticipantId (4 bytes) */
@@ -92,58 +98,68 @@ static int encomsp_recv_change_participant_control_level_pdu(EncomspServerContex
        end = (int) Stream_GetPosition(s);
 
        if ((beg + header->Length) < end)
-               return -1;
+       {
+               WLog_ERR(TAG, "Not enought data!");
+               return ERROR_INVALID_DATA;
+       }
 
        if ((beg + header->Length) > end)
        {
                if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end))
-                       return -1;
+               {
+                       WLog_ERR(TAG, "Not enought data!");
+                       return ERROR_INVALID_DATA;
+               }
 
                Stream_SetPosition(s, (beg + header->Length));
        }
 
-       if (context->ChangeParticipantControlLevel)
-       {
-               return context->ChangeParticipantControlLevel(context, &pdu);
-       }
+       IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu);
+       if (error)
+               WLog_ERR(TAG, "context->ChangeParticipantControlLevel failed with error %lu", error);
 
-       return 1;
+       return error;
 }
 
-static int encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s)
+static WIN32ERROR encomsp_server_receive_pdu(EncomspServerContext* context, wStream* s)
 {
-       int status = 1;
+       WIN32ERROR error = CHANNEL_RC_OK;
        ENCOMSP_ORDER_HEADER header;
 
        while (Stream_GetRemainingLength(s) > 0)
        {
-               if (encomsp_read_header(s, &header) < 0)
-                       return -1;
+               if ((error = encomsp_read_header(s, &header)))
+               {
+                       WLog_ERR(TAG, "encomsp_read_header failed with error %lu!", error);
+                       return error;
+               }
 
                WLog_INFO(TAG, "EncomspReceive: Type: %d Length: %d", header.Type, header.Length);
 
                switch (header.Type)
                {
                        case ODTYPE_PARTICIPANT_CTRL_CHANGED:
-                               status = encomsp_recv_change_participant_control_level_pdu(context, s, &header);
+                               if ((error = encomsp_recv_change_participant_control_level_pdu(context, s, &header)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_recv_change_participant_control_level_pdu failed with error %lu!", error);
+                                       return error;
+                               }
+
                                break;
 
                        default:
-                               status = -1;
+                               WLog_ERR(TAG, "header.Type unknown %d!", header.Type);
+                               return ERROR_INVALID_DATA;
                                break;
                }
-
-               if (status < 0)
-                       return -1;
        }
 
-       return status;
+       return error;
 }
 
 static void* encomsp_server_thread(void* arg)
 {
        wStream* s;
-       DWORD status;
        DWORD nCount;
        void* buffer;
        HANDLE events[8];
@@ -151,6 +167,7 @@ static void* encomsp_server_thread(void* arg)
        DWORD BytesReturned;
        ENCOMSP_ORDER_HEADER* header;
        EncomspServerContext* context;
+       WIN32ERROR error = CHANNEL_RC_OK;
 
        context = (EncomspServerContext*) arg;
 
@@ -159,6 +176,12 @@ static void* encomsp_server_thread(void* arg)
        ChannelEvent = NULL;
 
        s = Stream_New(NULL, 4096);
+       if (!s)
+       {
+               WLog_ERR(TAG, "Stream_New failed!");
+               ExitThread((DWORD) CHANNEL_RC_NO_MEMORY);
+               return NULL;
+       }
 
        if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
        {
@@ -174,7 +197,7 @@ static void* encomsp_server_thread(void* arg)
 
        while (1)
        {
-               status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
+               WaitForMultipleObjects(nCount, events, FALSE, INFINITE);
 
                if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
                {
@@ -184,10 +207,17 @@ static void* encomsp_server_thread(void* arg)
                WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);
                if (BytesReturned < 1)
                        continue;
-               Stream_EnsureRemainingCapacity(s, BytesReturned);
+               if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
+               {
+                       WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
+                       error = CHANNEL_RC_NO_MEMORY;
+                       break;
+               }
                if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
                        (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
                {
+                       WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
+                       error = ERROR_INTERNAL_ERROR;
                        break;
                }
 
@@ -199,40 +229,54 @@ static void* encomsp_server_thread(void* arg)
                        {
                                Stream_SealLength(s);
                                Stream_SetPosition(s, 0);
-                               encomsp_server_receive_pdu(context, s);
+                               if ((error = encomsp_server_receive_pdu(context, s)))
+                               {
+                                       WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %lu!", error);
+                                       break;
+                               }
                                Stream_SetPosition(s, 0);
                        }
                }
        }
 
        Stream_Free(s, TRUE);
-
+       ExitThread((DWORD)error);
        return NULL;
 }
 
-static int encomsp_server_start(EncomspServerContext* context)
+static WIN32ERROR encomsp_server_start(EncomspServerContext* context)
 {
        context->priv->ChannelHandle = WTSVirtualChannelOpen(context->vcm, WTS_CURRENT_SESSION, "encomsp");
 
        if (!context->priv->ChannelHandle)
-               return -1;
+               return CHANNEL_RC_BAD_CHANNEL;
 
-       context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+       if (!(context->priv->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
+       {
+               WLog_ERR(TAG, "CreateEvent failed!");
+               return ERROR_INTERNAL_ERROR;
+       }
 
-       context->priv->Thread = CreateThread(NULL, 0,
-                       (LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL);
+       if (!(context->priv->Thread = CreateThread(NULL, 0,
+                       (LPTHREAD_START_ROUTINE) encomsp_server_thread, (void*) context, 0, NULL)))
+       {
+               WLog_ERR(TAG, "CreateThread failed!");
+               CloseHandle(context->priv->StopEvent);
+               context->priv->StopEvent = NULL;
+               return ERROR_INTERNAL_ERROR;
+       }
 
-       return 0;
+       return CHANNEL_RC_OK;
 }
 
-static int encomsp_server_stop(EncomspServerContext* context)
+static WIN32ERROR encomsp_server_stop(EncomspServerContext* context)
 {
        SetEvent(context->priv->StopEvent);
 
        WaitForSingleObject(context->priv->Thread, INFINITE);
        CloseHandle(context->priv->Thread);
 
-       return 0;
+       return CHANNEL_RC_OK;
 }
 
 EncomspServerContext* encomsp_server_context_new(HANDLE vcm)
@@ -250,9 +294,11 @@ EncomspServerContext* encomsp_server_context_new(HANDLE vcm)
 
                context->priv = (EncomspServerPrivate*) calloc(1, sizeof(EncomspServerPrivate));
 
-               if (context->priv)
+               if (!context->priv)
                {
-
+                       WLog_ERR(TAG, "calloc failed!");
+                       free(context);
+                       return NULL;
                }
        }
 
index 83868d6..5a13ded 100644 (file)
@@ -723,9 +723,9 @@ void xf_toggle_control(xfContext* xfc)
        xfc->controlToggle = !xfc->controlToggle;
 }
 
-int xf_encomsp_participant_created(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated)
+WIN32ERROR xf_encomsp_participant_created(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated)
 {
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
 void xf_encomsp_init(xfContext* xfc, EncomspClientContext* encomsp)
index e8b8466..f2230a5 100644 (file)
@@ -3,6 +3,8 @@
  * Multiparty Virtual Channel
  *
  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +23,7 @@
 #define FREERDP_CHANNEL_CLIENT_ENCOMSP_H
 
 #include <freerdp/channels/encomsp.h>
+#include <winpr/win32error.h>
 
 /**
  * Client Interface
 
 typedef struct _encomsp_client_context EncomspClientContext;
 
-typedef int (*pcEncomspFilterUpdated)(EncomspClientContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated);
-typedef int (*pcEncomspApplicationCreated)(EncomspClientContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated);
-typedef int (*pcEncomspApplicationRemoved)(EncomspClientContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved);
-typedef int (*pcEncomspWindowCreated)(EncomspClientContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated);
-typedef int (*pcEncomspWindowRemoved)(EncomspClientContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved);
-typedef int (*pcEncomspShowWindow)(EncomspClientContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow);
-typedef int (*pcEncomspParticipantCreated)(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated);
-typedef int (*pcEncomspParticipantRemoved)(EncomspClientContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved);
-typedef int (*pcEncomspChangeParticipantControlLevel)(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel);
-typedef int (*pcEncomspGraphicsStreamPaused)(EncomspClientContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused);
-typedef int (*pcEncomspGraphicsStreamResumed)(EncomspClientContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed);
+typedef WIN32ERROR (*pcEncomspFilterUpdated)(EncomspClientContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated);
+typedef WIN32ERROR (*pcEncomspApplicationCreated)(EncomspClientContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated);
+typedef WIN32ERROR (*pcEncomspApplicationRemoved)(EncomspClientContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved);
+typedef WIN32ERROR (*pcEncomspWindowCreated)(EncomspClientContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated);
+typedef WIN32ERROR (*pcEncomspWindowRemoved)(EncomspClientContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved);
+typedef WIN32ERROR (*pcEncomspShowWindow)(EncomspClientContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow);
+typedef WIN32ERROR (*pcEncomspParticipantCreated)(EncomspClientContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated);
+typedef WIN32ERROR (*pcEncomspParticipantRemoved)(EncomspClientContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved);
+typedef WIN32ERROR (*pcEncomspChangeParticipantControlLevel)(EncomspClientContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel);
+typedef WIN32ERROR (*pcEncomspGraphicsStreamPaused)(EncomspClientContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused);
+typedef WIN32ERROR (*pcEncomspGraphicsStreamResumed)(EncomspClientContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed);
 
 struct _encomsp_client_context
 {
index a5037e6..678b360 100644 (file)
@@ -3,6 +3,8 @@
  * Multiparty Virtual Channel
  *
  * Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2015 Thincast Technologies GmbH
+ * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 typedef struct _encomsp_server_context EncomspServerContext;
 typedef struct _encomsp_server_private EncomspServerPrivate;
 
-typedef int (*psEncomspStart)(EncomspServerContext* context);
-typedef int (*psEncomspStop)(EncomspServerContext* context);
+typedef WIN32ERROR (*psEncomspStart)(EncomspServerContext* context);
+typedef WIN32ERROR (*psEncomspStop)(EncomspServerContext* context);
 
-typedef int (*psEncomspFilterUpdated)(EncomspServerContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated);
-typedef int (*psEncomspApplicationCreated)(EncomspServerContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated);
-typedef int (*psEncomspApplicationRemoved)(EncomspServerContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved);
-typedef int (*psEncomspWindowCreated)(EncomspServerContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated);
-typedef int (*psEncomspWindowRemoved)(EncomspServerContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved);
-typedef int (*psEncomspShowWindow)(EncomspServerContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow);
-typedef int (*psEncomspParticipantCreated)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated);
-typedef int (*psEncomspParticipantRemoved)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved);
-typedef int (*psEncomspChangeParticipantControlLevel)(EncomspServerContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel);
-typedef int (*psEncomspGraphicsStreamPaused)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused);
-typedef int (*psEncomspGraphicsStreamResumed)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed);
+typedef WIN32ERROR (*psEncomspFilterUpdated)(EncomspServerContext* context, ENCOMSP_FILTER_UPDATED_PDU* filterUpdated);
+typedef WIN32ERROR (*psEncomspApplicationCreated)(EncomspServerContext* context, ENCOMSP_APPLICATION_CREATED_PDU* applicationCreated);
+typedef WIN32ERROR (*psEncomspApplicationRemoved)(EncomspServerContext* context, ENCOMSP_APPLICATION_REMOVED_PDU* applicationRemoved);
+typedef WIN32ERROR (*psEncomspWindowCreated)(EncomspServerContext* context, ENCOMSP_WINDOW_CREATED_PDU* windowCreated);
+typedef WIN32ERROR (*psEncomspWindowRemoved)(EncomspServerContext* context, ENCOMSP_WINDOW_REMOVED_PDU* windowRemoved);
+typedef WIN32ERROR (*psEncomspShowWindow)(EncomspServerContext* context, ENCOMSP_SHOW_WINDOW_PDU* showWindow);
+typedef WIN32ERROR (*psEncomspParticipantCreated)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_CREATED_PDU* participantCreated);
+typedef WIN32ERROR (*psEncomspParticipantRemoved)(EncomspServerContext* context, ENCOMSP_PARTICIPANT_REMOVED_PDU* participantRemoved);
+typedef WIN32ERROR (*psEncomspChangeParticipantControlLevel)(EncomspServerContext* context, ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* changeParticipantControlLevel);
+typedef WIN32ERROR (*psEncomspGraphicsStreamPaused)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_PAUSED_PDU* graphicsStreamPaused);
+typedef WIN32ERROR (*psEncomspGraphicsStreamResumed)(EncomspServerContext* context, ENCOMSP_GRAPHICS_STREAM_RESUMED_PDU* graphicsStreamResumed);
 
 struct _encomsp_server_context
 {
index 61bb2e5..7e8cc2c 100644 (file)
@@ -27,7 +27,7 @@
 
 #define TAG SERVER_TAG("shadow")
 
-static int encomsp_change_participant_control_level(EncomspServerContext* context,
+static WIN32ERROR encomsp_change_participant_control_level(EncomspServerContext* context,
                ENCOMSP_CHANGE_PARTICIPANT_CONTROL_LEVEL_PDU* pdu)
 {
        BOOL inLobby;
@@ -90,7 +90,7 @@ static int encomsp_change_participant_control_level(EncomspServerContext* contex
                client->inLobby = inLobby;
        }
 
-       return 1;
+       return CHANNEL_RC_OK;
 }
 
 int shadow_client_encomsp_init(rdpShadowClient* client)