libfreerdp-core: change return values for PDU processing
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 8 Jan 2013 22:18:10 +0000 (17:18 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Tue, 8 Jan 2013 22:18:10 +0000 (17:18 -0500)
include/freerdp/update.h
libfreerdp/core/fastpath.c
libfreerdp/core/rdp.c
libfreerdp/core/surface.c
libfreerdp/core/surface.h
libfreerdp/core/update.c

index 71cd471..526f22f 100644 (file)
 
 typedef struct rdp_update rdpUpdate;
 
+#include <winpr/crt.h>
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+#include <winpr/collections.h>
+
 #include <freerdp/rail.h>
 #include <freerdp/types.h>
 #include <freerdp/freerdp.h>
@@ -191,6 +196,9 @@ struct rdp_update
 
        SURFACE_BITS_COMMAND surface_bits_command;
        SURFACE_FRAME_MARKER surface_frame_marker;
+
+       HANDLE thread;
+       wQueue* queue;
 };
 
 #endif /* FREERDP_UPDATE_H */
index b6c0124..848bfd6 100644 (file)
@@ -340,7 +340,7 @@ static BOOL fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
        return TRUE;
 }
 
-BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
+int fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
 {
        rdpUpdate* update = fastpath->rdp->update;
 
@@ -349,15 +349,12 @@ BOOL fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
        while (stream_get_left(s) >= 3)
        {
                if (!fastpath_recv_update_data(fastpath, s))
-               {
-                       /* XXX: Do we need to call EndPaint? */
-                       return FALSE;
-               }
+                       return -1;
        }
 
        IFCALL(update->EndPaint, update->context);
 
-       return TRUE;
+       return 0;
 }
 
 static BOOL fastpath_read_input_event_header(STREAM* s, BYTE* eventFlags, BYTE* eventCode)
index 2c10b1b..1b068b5 100644 (file)
@@ -480,7 +480,7 @@ void rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, STREAM* s)
                rdp_print_errinfo(rdp->errorInfo);
 }
 
-BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
+int rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
 {
        BYTE type;
        UINT16 length;
@@ -507,7 +507,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
                else
                {
                        printf("decompress_rdp() failed\n");
-                       return FALSE;
+                       return -1;
                }
                stream_seek(s, compressed_len - 18);
        }
@@ -522,7 +522,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
        {
                case DATA_PDU_TYPE_UPDATE:
                        if (!update_recv(rdp->update, comp_stream))
-                               return FALSE;
+                               return -1;
                        break;
 
                case DATA_PDU_TYPE_CONTROL:
@@ -611,7 +611,7 @@ BOOL rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
                stream_free(comp_stream);
        }
 
-       return TRUE;
+       return 0;
 }
 
 BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
@@ -624,7 +624,7 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
 
        if (type == PDU_TYPE_DATA)
        {
-               return rdp_recv_data_pdu(rdp, s);
+               return (rdp_recv_data_pdu(rdp, s) < 0) ? FALSE : TRUE;
        }
        else if (type == PDU_TYPE_SERVER_REDIRECTION)
        {
@@ -712,7 +712,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, UINT16 securityFlags)
  * @param s stream
  */
 
-static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
+static int rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
 {
        UINT16 length;
        UINT16 pduType;
@@ -725,7 +725,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
        if (!rdp_read_header(rdp, s, &length, &channelId))
        {
                printf("Incorrect RDP header.\n");
-               return FALSE;
+               return -1;
        }
 
        if (rdp->settings->DisableEncryption)
@@ -737,7 +737,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
                        if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
                        {
                                printf("rdp_decrypt failed\n");
-                               return FALSE;
+                               return -1;
                        }
                }
 
@@ -749,7 +749,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
                         */
                        s->p -= 2;
                        rdp_recv_enhanced_security_redirection_packet(rdp, s);
-                       return TRUE;
+                       return -1;
                }
        }
 
@@ -770,16 +770,16 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
                        switch (pduType)
                        {
                                case PDU_TYPE_DATA:
-                                       if (!rdp_recv_data_pdu(rdp, s))
+                                       if (rdp_recv_data_pdu(rdp, s) < 0)
                                        {
                                                printf("rdp_recv_data_pdu failed\n");
-                                               return FALSE;
+                                               return -1;
                                        }
                                        break;
 
                                case PDU_TYPE_DEACTIVATE_ALL:
                                        if (!rdp_recv_deactivate_all(rdp, s))
-                                               return FALSE;
+                                               return -1;
                                        break;
 
                                case PDU_TYPE_SERVER_REDIRECTION:
@@ -794,10 +794,10 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
                }
        }
 
-       return TRUE;
+       return 0;
 }
 
-static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
+static int rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
 {
        UINT16 length;
        rdpFastPath* fastpath;
@@ -808,7 +808,7 @@ static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
        if ((length == 0) || (length > stream_get_left(s)))
        {
                printf("incorrect FastPath PDU header length %d\n", length);
-               return FALSE;
+               return -1;
        }
 
        if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
@@ -819,7 +819,7 @@ static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
        return fastpath_recv_updates(rdp->fastpath, s);
 }
 
-static BOOL rdp_recv_pdu(rdpRdp* rdp, STREAM* s)
+static int rdp_recv_pdu(rdpRdp* rdp, STREAM* s)
 {
        if (tpkt_verify_header(s))
                return rdp_recv_tpkt_pdu(rdp, s);
@@ -842,58 +842,58 @@ void rdp_recv(rdpRdp* rdp)
        rdp_recv_pdu(rdp, s);
 }
 
-static BOOL rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
+static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
 {
+       int status = 0;
        rdpRdp* rdp = (rdpRdp*) extra;
 
        switch (rdp->state)
        {
                case CONNECTION_STATE_NEGO:
                        if (!rdp_client_connect_mcs_connect_response(rdp, s))
-                               return -1;
+                               status = -1;
                        break;
 
                case CONNECTION_STATE_MCS_ATTACH_USER:
                        if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
-                               return -1;
+                               status = -1;
                        break;
 
                case CONNECTION_STATE_MCS_CHANNEL_JOIN:
                        if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s))
-                               return -1;
+                               status = -1;
                        break;
 
                case CONNECTION_STATE_LICENSE:
                        if (!rdp_client_connect_license(rdp, s))
-                               return -1;
+                               status = -1;
                        break;
 
                case CONNECTION_STATE_CAPABILITY:
                        if (!rdp_client_connect_demand_active(rdp, s))
                        {
                                printf("rdp_client_connect_demand_active failed\n");
-                               return -1;
+                               status = -1;
                        }
                        break;
 
                case CONNECTION_STATE_FINALIZATION:
-                       if (!rdp_recv_pdu(rdp, s))
-                               return -1;
-                       if (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE)
+                       status = rdp_recv_pdu(rdp, s);
+                       if ((status >= 0) && (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE))
                                rdp->state = CONNECTION_STATE_ACTIVE;
                        break;
 
                case CONNECTION_STATE_ACTIVE:
-                       if (!rdp_recv_pdu(rdp, s))
-                               return -1;
+                       status = rdp_recv_pdu(rdp, s);
                        break;
 
                default:
                        printf("Invalid state %d\n", rdp->state);
-                       return -1;
+                       status = -1;
+                       break;
        }
 
-       return 0;
+       return status;
 }
 
 int rdp_send_channel_data(rdpRdp* rdp, int channel_id, BYTE* data, int size)
index 9c15742..e550503 100644 (file)
@@ -76,7 +76,7 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
        return 6;
 }
 
-BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
+int update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
 {
        BYTE* mark;
        UINT16 cmdType;
@@ -102,7 +102,7 @@ BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
 
                        default:
                                DEBUG_WARN("unknown cmdType 0x%X", cmdType);
-                               return FALSE;
+                               return -1;
                }
 
                size -= cmdLength;
@@ -113,7 +113,8 @@ BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s)
                        pcap_flush(update->pcap_rfx);
                }
        }
-       return TRUE;
+
+       return 0;
 }
 
 void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd)
index 82dda24..38ebbe1 100644 (file)
@@ -33,7 +33,7 @@ enum SURFCMD_CMDTYPE
        CMDTYPE_STREAM_SURFACE_BITS = 0x0006
 };
 
-BOOL update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s);
+int update_recv_surfcmds(rdpUpdate* update, UINT32 size, STREAM* s);
 
 void update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
 void update_write_surfcmd_frame_marker(STREAM* s, UINT16 frameAction, UINT32 frameId);
index 7f747c6..9baea0e 100644 (file)
@@ -22,6 +22,7 @@
 #endif
 
 #include <winpr/crt.h>
+#include <winpr/thread.h>
 
 #include "update.h"
 #include "surface.h"
@@ -620,6 +621,20 @@ void update_register_client_callbacks(rdpUpdate* update)
        update->SuppressOutput = update_send_suppress_output;
 }
 
+static void* update_thread(void* arg)
+{
+       rdpUpdate* update;
+
+       update = (rdpUpdate*) arg;
+
+       while (WaitForSingleObject(Queue_Event(update->queue), INFINITE) == WAIT_OBJECT_0)
+       {
+
+       }
+
+       return NULL;
+}
+
 rdpUpdate* update_new(rdpRdp* rdp)
 {
        rdpUpdate* update;
@@ -657,6 +672,10 @@ rdpUpdate* update_new(rdpRdp* rdp)
                deleteList->cIndices = 0;
 
                update->SuppressOutput = update_send_suppress_output;
+
+               update->queue = Queue_New(TRUE, -1, -1);
+
+               update->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) update_thread, update, 0, NULL);
        }
 
        return update;
@@ -679,7 +698,9 @@ void update_free(rdpUpdate* update)
                free(update->secondary);
                free(update->altsec);
                free(update->window);
+
+               CloseHandle(update->thread);
+
                free(update);
        }
 }
-