Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d290cb1e53
3
.gitignore
vendored
3
.gitignore
vendored
@ -30,9 +30,6 @@ docs/api
|
|||||||
ipch
|
ipch
|
||||||
Debug
|
Debug
|
||||||
|
|
||||||
# test files
|
|
||||||
*.pcap
|
|
||||||
|
|
||||||
# Binaries
|
# Binaries
|
||||||
*.a
|
*.a
|
||||||
*.so
|
*.so
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
BIN
server/test/rfx_test.pcap
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user