Windows XP can send short (and non-standard) DEACTIVATE_ALL PDUs. Handle them properly.
authorPawel Jakub Dawidek <pawel@dawidek.net>
Mon, 6 Feb 2012 21:34:16 +0000 (22:34 +0100)
committerPawel Jakub Dawidek <pawel@dawidek.net>
Mon, 6 Feb 2012 21:39:43 +0000 (22:39 +0100)
libfreerdp-core/activation.c
libfreerdp-core/rdp.c

index 5c781b8..de3b7f9 100644 (file)
@@ -277,9 +277,16 @@ boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s)
 {
        uint16 lengthSourceDescriptor;
 
-       stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
-       stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
-       stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
+       /*
+        * Windows XP can send short DEACTIVATE_ALL PDU that doesn't contain
+        * the following fields.
+        */
+       if (stream_get_left(s) > 0)
+       {
+               stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */
+               stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
+               stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
+       }
 
        rdp->state = CONNECTION_STATE_CAPABILITY;
 
index 5784929..702fb94 100644 (file)
@@ -98,9 +98,13 @@ boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, u
                return false;
 
        stream_read_uint16(s, *type); /* pduType */
-       stream_read_uint16(s, *channel_id); /* pduSource */
        *type &= 0x0F; /* type is in the 4 least significant bits */
 
+       if (*length > 4)
+               stream_read_uint16(s, *channel_id); /* pduSource */
+       else /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
+               *channel_id = 0;
+
        return true;
 }