diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index daa697cc9..fb0269c23 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1371,6 +1371,10 @@ void rdp_read_bitmap_codecs_capability_set(STREAM* s, rdpSettings* settings) */ void rdp_write_rfx_client_capability_container(STREAM* s, rdpSettings* settings) { + uint16 captureFlags; + + captureFlags = settings->dump_rfx ? 0 : CARDP_CAPS_CAPTURE_NON_CAC; + stream_write_uint16(s, 49); /* codecPropertiesLength */ /* TS_RFX_CLNT_CAPS_CONTAINER */ diff --git a/libfreerdp-core/fastpath.c b/libfreerdp-core/fastpath.c index 848170080..322417da1 100644 --- a/libfreerdp-core/fastpath.c +++ b/libfreerdp-core/fastpath.c @@ -457,9 +457,10 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s) uint16 length; length = stream_get_length(s); + if (length > FASTPATH_MAX_PACKET_SIZE) { - printf("Maximum FastPath Update PDU length is %d\n", FASTPATH_MAX_PACKET_SIZE); + printf("Maximum FastPath Update PDU length is %d (actual:%d)\n", FASTPATH_MAX_PACKET_SIZE, length); return False; } @@ -477,29 +478,64 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s) boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s) { + int fragment; uint16 length; + uint16 maxLength; uint32 totalLength; STREAM* update; totalLength = stream_get_length(s); - update = fastpath_update_pdu_init(fastpath); + maxLength = FASTPATH_MAX_PACKET_SIZE - 6; - if (totalLength <= FASTPATH_MAX_PACKET_SIZE) + if (totalLength <= maxLength) { + update = fastpath_update_pdu_init(fastpath); stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_SINGLE << 4)); stream_write_uint16(update, totalLength); stream_write(update, s->data, totalLength); return fastpath_send_update_pdu(fastpath, update); } + fragment = 0; while (totalLength > 0) { - if (totalLength < FASTPATH_MAX_PACKET_SIZE) + if (totalLength < maxLength) length = totalLength; else - length = FASTPATH_MAX_PACKET_SIZE; + length = maxLength; totalLength -= length; + update = fastpath_update_pdu_init(fastpath); + + if (fragment == 0) + { + stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_FIRST << 4)); + stream_write_uint16(update, length); + stream_write(update, s->p, length); + fastpath_send_update_pdu(fastpath, update); + s->p += length; + } + else + { + if (totalLength == 0) + { + stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_LAST << 4)); + stream_write_uint16(update, length); + stream_write(update, s->p, length); + fastpath_send_update_pdu(fastpath, update); + s->p += length; + } + else + { + stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_NEXT << 4)); + stream_write_uint16(update, length); + stream_write(update, s->p, length); + fastpath_send_update_pdu(fastpath, update); + s->p += length; + } + } + + fragment++; } return True; diff --git a/libfreerdp-core/surface.c b/libfreerdp-core/surface.c index fb3075c4f..ad55f5d3f 100644 --- a/libfreerdp-core/surface.c +++ b/libfreerdp-core/surface.c @@ -60,16 +60,14 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s) boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s) { + uint8* mark; uint16 cmdType; - - if (update->dump_rfx) - { - pcap_add_record(update->pcap_rfx, s->p, size); - pcap_flush(update->pcap_rfx); - } + uint16 cmdLength; while (size > 2) { + stream_get_mark(s, mark); + stream_read_uint16(s, cmdType); size -= 2; @@ -77,17 +75,25 @@ boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s) { case CMDTYPE_SET_SURFACE_BITS: case CMDTYPE_STREAM_SURFACE_BITS: - size -= update_recv_surfcmd_surface_bits(update, s); + cmdLength = update_recv_surfcmd_surface_bits(update, s); break; case CMDTYPE_FRAME_MARKER: - size -= update_recv_surfcmd_frame_marker(update, s); + cmdLength = update_recv_surfcmd_frame_marker(update, s); break; default: DEBUG_WARN("unknown cmdType 0x%X", cmdType); return False; } + + size -= cmdLength; + + if (update->dump_rfx) + { + pcap_add_record(update->pcap_rfx, mark, cmdLength + 2); + pcap_flush(update->pcap_rfx); + } } return True; } diff --git a/server/test/freerdp_server.c b/server/test/freerdp_server.c index afab4a8b9..7aaa3129d 100644 --- a/server/test/freerdp_server.c +++ b/server/test/freerdp_server.c @@ -286,6 +286,8 @@ boolean test_peer_post_connect(freerdp_peer* client) test_peer_draw_background(client); test_peer_load_icon(client); + //client->update->dump_rfx = True; + if (client->update->dump_rfx) { test_peer_dump_rfx(client); @@ -324,13 +326,13 @@ void test_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uin static void* test_peer_mainloop(void* arg) { - freerdp_peer* client = (freerdp_peer*)arg; int i; int fds; int max_fds; int rcount; void* rfds[32]; fd_set rfds_set; + freerdp_peer* client = (freerdp_peer*) arg; memset(rfds, 0, sizeof(rfds));