Merge remote-tracking branch 'upstream/master'

This commit is contained in:
qubit 2011-08-29 03:25:48 +05:30
commit d290cb1e53
11 changed files with 96 additions and 67 deletions

3
.gitignore vendored
View File

@ -30,9 +30,6 @@ docs/api
ipch ipch
Debug Debug
# test files
*.pcap
# Binaries # Binaries
*.a *.a
*.so *.so

View File

@ -298,7 +298,9 @@ struct rdp_settings
boolean frame_acknowledge; boolean frame_acknowledge;
boolean dump_rfx; boolean dump_rfx;
boolean play_rfx;
char* dump_rfx_file; char* dump_rfx_file;
char* play_rfx_file;
boolean remote_app; boolean remote_app;
uint8 num_icon_caches; uint8 num_icon_caches;

View File

@ -1076,6 +1076,7 @@ struct rdp_update
void* param2; void* param2;
boolean dump_rfx; boolean dump_rfx;
boolean play_rfx;
rdpPcap* pcap_rfx; rdpPcap* pcap_rfx;
pcBeginPaint BeginPaint; pcBeginPaint BeginPaint;

View File

@ -73,6 +73,26 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
return length; return length;
} }
inline void fastpath_read_update_header(STREAM* s, uint8* updateCode, uint8* fragmentation, uint8* compression)
{
uint8 updateHeader;
stream_read_uint8(s, updateHeader);
*updateCode = updateHeader & 0x0F;
*fragmentation = (updateHeader >> 4) & 0x03;
*compression = (updateHeader >> 6) & 0x03;
}
inline void fastpath_write_update_header(STREAM* s, uint8 updateCode, uint8 fragmentation, uint8 compression)
{
uint8 updateHeader = 0;
updateHeader |= updateCode & 0x0F;
updateHeader |= (fragmentation << 4) & 0x03;
updateHeader |= (compression << 6) & 0x03;
stream_write_uint8(s, updateHeader);
}
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s) boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s)
{ {
/* TODO: fipsInformation */ /* TODO: fipsInformation */
@ -122,7 +142,7 @@ static void fastpath_recv_update_common(rdpFastPath* fastpath, STREAM* s)
} }
} }
static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16 size, STREAM* s) static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint32 size, STREAM* s)
{ {
switch (updateCode) switch (updateCode)
{ {
@ -175,19 +195,16 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16
static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s) static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
{ {
uint8 updateHeader; uint16 size;
int next_pos;
uint32 totalSize;
uint8 updateCode; uint8 updateCode;
uint8 fragmentation; uint8 fragmentation;
uint8 compression; uint8 compression;
uint8 compressionFlags; uint8 compressionFlags;
uint16 size;
STREAM* update_stream; STREAM* update_stream;
int next_pos;
stream_read_uint8(s, updateHeader); fastpath_read_update_header(s, &updateCode, &fragmentation, &compression);
updateCode = updateHeader & 0x0F;
fragmentation = (updateHeader >> 4) & 0x03;
compression = (updateHeader >> 6) & 0x03;
if (compression == FASTPATH_OUTPUT_COMPRESSION_USED) if (compression == FASTPATH_OUTPUT_COMPRESSION_USED)
stream_read_uint8(s, compressionFlags); stream_read_uint8(s, compressionFlags);
@ -207,6 +224,7 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
update_stream = NULL; update_stream = NULL;
if (fragmentation == FASTPATH_FRAGMENT_SINGLE) if (fragmentation == FASTPATH_FRAGMENT_SINGLE)
{ {
totalSize = size;
update_stream = s; update_stream = s;
} }
else else
@ -220,13 +238,13 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
if (fragmentation == FASTPATH_FRAGMENT_LAST) if (fragmentation == FASTPATH_FRAGMENT_LAST)
{ {
update_stream = fastpath->updateData; update_stream = fastpath->updateData;
size = stream_get_length(update_stream); totalSize = stream_get_length(update_stream);
stream_set_pos(update_stream, 0); stream_set_pos(update_stream, 0);
} }
} }
if (update_stream) if (update_stream)
fastpath_recv_update(fastpath, updateCode, size, update_stream); fastpath_recv_update(fastpath, updateCode, totalSize, update_stream);
stream_set_pos(s, next_pos); stream_set_pos(s, next_pos);
} }
@ -482,60 +500,30 @@ boolean fastpath_send_fragmented_update_pdu(rdpFastPath* fastpath, STREAM* s)
uint16 length; uint16 length;
uint16 maxLength; uint16 maxLength;
uint32 totalLength; uint32 totalLength;
uint8 fragmentation;
STREAM* update; STREAM* update;
totalLength = stream_get_length(s);
maxLength = FASTPATH_MAX_PACKET_SIZE - 6; maxLength = FASTPATH_MAX_PACKET_SIZE - 6;
totalLength = stream_get_length(s);
stream_set_pos(s, 0);
if (totalLength <= maxLength) for (fragment = 0; totalLength > 0; fragment++)
{ {
update = fastpath_update_pdu_init(fastpath); update = fastpath_update_pdu_init(fastpath);
stream_write_uint8(update, FASTPATH_UPDATETYPE_SURFCMDS | (FASTPATH_FRAGMENT_SINGLE << 4)); length = MIN(maxLength, totalLength);
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 < maxLength)
length = totalLength;
else
length = maxLength;
totalLength -= length; totalLength -= length;
update = fastpath_update_pdu_init(fastpath);
if (fragment == 0) if (totalLength == 0)
{ fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST;
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 else
{ fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT;
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++; fastpath_write_update_header(update, FASTPATH_UPDATETYPE_SURFCMDS, fragmentation, 0);
stream_write_uint16(update, length);
stream_write(update, s->p, length);
stream_seek(s, length);
fastpath_send_update_pdu(fastpath, update);
} }
return True; return True;
@ -586,19 +574,17 @@ boolean fastpath_send_surfcmd_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_C
} }
fragment_size = MIN(FASTPATH_MAX_PACKET_SIZE - stream_get_length(s), bitmapDataLength); fragment_size = MIN(FASTPATH_MAX_PACKET_SIZE - stream_get_length(s), bitmapDataLength);
if (fragment_size == bitmapDataLength) if (fragment_size == bitmapDataLength)
{
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST); fragmentation = (i == 0 ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST);
}
else else
{
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT); fragmentation = (i == 0 ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT);
}
size += fragment_size; size += fragment_size;
ep = stream_get_pos(s); ep = stream_get_pos(s);
stream_set_pos(s, bp); stream_set_pos(s, bp);
stream_write_uint8(s, FASTPATH_UPDATETYPE_SURFCMDS | (fragmentation << 4)); fastpath_write_update_header(s, FASTPATH_UPDATETYPE_SURFCMDS, fragmentation, 0);
stream_write_uint16(s, size); stream_write_uint16(s, size);
stream_set_pos(s, ep); stream_set_pos(s, ep);

View File

@ -20,6 +20,7 @@
#include "rdp.h" #include "rdp.h"
#include "input.h" #include "input.h"
#include "update.h" #include "update.h"
#include "surface.h"
#include "transport.h" #include "transport.h"
#include "connection.h" #include "connection.h"
@ -46,6 +47,37 @@ boolean freerdp_connect(freerdp* instance)
} }
IFCALL(instance->PostConnect, instance); IFCALL(instance->PostConnect, instance);
if (instance->settings->play_rfx)
{
STREAM* s;
rdpUpdate* update;
pcap_record record;
s = stream_new(1024);
instance->update->play_rfx = instance->settings->play_rfx;
instance->update->pcap_rfx = pcap_open(instance->settings->play_rfx_file, False);
update = instance->update;
while (pcap_has_next_record(update->pcap_rfx))
{
pcap_get_next_record_header(update->pcap_rfx, &record);
s->data = xrealloc(s->data, record.length);
record.data = s->data;
s->size = record.length;
pcap_get_next_record_content(update->pcap_rfx, &record);
stream_set_pos(s, 0);
update->BeginPaint(update);
update_recv_surfcmds(update, s->size, s);
update->EndPaint(update);
}
xfree(s->data);
return True;
}
} }
return status; return status;

View File

@ -58,11 +58,11 @@ static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
return 6; return 6;
} }
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s) boolean update_recv_surfcmds(rdpUpdate* update, uint32 size, STREAM* s)
{ {
uint8* mark; uint8* mark;
uint16 cmdType; uint16 cmdType;
uint16 cmdLength; uint32 cmdLength;
while (size > 2) while (size > 2)
{ {

View File

@ -39,7 +39,7 @@ enum SURFCMD_FRAMEACTION
SURFACECMD_FRAMEACTION_END = 0x0001 SURFACECMD_FRAMEACTION_END = 0x0001
}; };
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s); boolean 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_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
void update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId); void update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId);

View File

@ -293,6 +293,17 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv,
settings->dump_rfx_file = xstrdup(argv[index]); settings->dump_rfx_file = xstrdup(argv[index]);
settings->dump_rfx = True; settings->dump_rfx = True;
} }
else if (strcmp("--play-rfx", argv[index]) == 0)
{
index++;
if (index == argc)
{
printf("missing file name\n");
return -1;
}
settings->play_rfx_file = xstrdup(argv[index]);
settings->play_rfx = True;
}
else if (strcmp("-m", argv[index]) == 0) else if (strcmp("-m", argv[index]) == 0)
{ {
settings->mouse_motion = 0; settings->mouse_motion = 0;

View File

@ -149,7 +149,7 @@ rdpPcap* pcap_open(char* name, boolean write)
pcap->header.version_minor = 4; pcap->header.version_minor = 4;
pcap->header.thiszone = 0; pcap->header.thiszone = 0;
pcap->header.sigfigs = 0; pcap->header.sigfigs = 0;
pcap->header.snaplen = 65535; pcap->header.snaplen = 0xFFFFFFFF;
pcap->header.network = 0; pcap->header.network = 0;
pcap_write_header(pcap, &pcap->header); pcap_write_header(pcap, &pcap->header);
} }

View File

@ -286,7 +286,7 @@ boolean test_peer_post_connect(freerdp_peer* client)
test_peer_draw_background(client); test_peer_draw_background(client);
test_peer_load_icon(client); test_peer_load_icon(client);
//client->update->dump_rfx = True; client->update->dump_rfx = True;
if (client->update->dump_rfx) if (client->update->dump_rfx)
{ {

BIN
server/test/rfx_test.pcap Normal file

Binary file not shown.