mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #58 from llyzs/server
Server: add keyboard/mouse input and RemoteFX update processing
This commit is contained in:
commit
313e1dcfd2
|
@ -59,6 +59,9 @@ typedef void (*pcExtendedMouseEvent)(rdpInput* input, uint16 flags, uint16 x, ui
|
|||
struct rdp_input
|
||||
{
|
||||
void* rdp;
|
||||
void* param1;
|
||||
void* param2;
|
||||
|
||||
pcSynchronizeEvent SynchronizeEvent;
|
||||
pcKeyboardEvent KeyboardEvent;
|
||||
pcUnicodeKeyboardEvent UnicodeKeyboardEvent;
|
||||
|
|
|
@ -25,11 +25,14 @@ typedef struct rdp_freerdp_peer freerdp_peer;
|
|||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/input.h>
|
||||
#include <freerdp/update.h>
|
||||
|
||||
typedef boolean (*psPeerInitialize)(freerdp_peer* client);
|
||||
typedef boolean (*psPeerGetFileDescriptor)(freerdp_peer* client, void** rfds, int* rcount);
|
||||
typedef boolean (*psPeerCheckFileDescriptor)(freerdp_peer* client);
|
||||
typedef void (*psPeerDisconnect)(freerdp_peer* client);
|
||||
typedef boolean (*psPeerPostConnect)(freerdp_peer* client);
|
||||
|
||||
struct rdp_freerdp_peer
|
||||
{
|
||||
|
@ -39,12 +42,16 @@ struct rdp_freerdp_peer
|
|||
void* param3;
|
||||
void* param4;
|
||||
|
||||
rdpInput* input;
|
||||
rdpUpdate* update;
|
||||
rdpSettings* settings;
|
||||
|
||||
psPeerInitialize Initialize;
|
||||
psPeerGetFileDescriptor GetFileDescriptor;
|
||||
psPeerCheckFileDescriptor CheckFileDescriptor;
|
||||
psPeerDisconnect Disconnect;
|
||||
|
||||
psPeerPostConnect PostConnect;
|
||||
};
|
||||
|
||||
FREERDP_API freerdp_peer* freerdp_peer_new(int sockfd);
|
||||
|
|
|
@ -76,6 +76,8 @@ set(LIBFREERDP_CORE_SRCS
|
|||
tpkt.h
|
||||
fastpath.c
|
||||
fastpath.h
|
||||
surface.c
|
||||
surface.h
|
||||
transport.c
|
||||
transport.h
|
||||
update.c
|
||||
|
|
|
@ -34,7 +34,7 @@ void rdp_write_synchronize_pdu(STREAM* s, rdpSettings* settings)
|
|||
stream_write_uint16(s, settings->pdu_source); /* targetUser (2 bytes) */
|
||||
}
|
||||
|
||||
boolean rdp_read_server_synchronize_pdu(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp)
|
|||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_read_client_synchronize_pdu(STREAM* s)
|
||||
boolean rdp_recv_client_synchronize_pdu(STREAM* s)
|
||||
{
|
||||
uint16 messageType;
|
||||
|
||||
|
@ -78,7 +78,7 @@ boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp)
|
|||
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
boolean rdp_read_control_pdu(STREAM* s, uint16* action)
|
||||
boolean rdp_recv_control_pdu(STREAM* s, uint16* action)
|
||||
{
|
||||
if (stream_get_left(s) < 8)
|
||||
return False;
|
||||
|
@ -97,11 +97,11 @@ void rdp_write_client_control_pdu(STREAM* s, uint16 action)
|
|||
stream_write_uint32(s, 0); /* controlId (4 bytes) */
|
||||
}
|
||||
|
||||
boolean rdp_read_server_control_pdu(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 action;
|
||||
|
||||
rdp_read_control_pdu(s, &action);
|
||||
rdp_recv_control_pdu(s, &action);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
|
|||
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
boolean rdp_read_client_font_list_pdu(STREAM* s)
|
||||
boolean rdp_recv_client_font_list_pdu(STREAM* s)
|
||||
{
|
||||
if (stream_get_left(s) < 8)
|
||||
return False;
|
||||
|
@ -210,7 +210,7 @@ boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags)
|
|||
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id);
|
||||
}
|
||||
|
||||
boolean rdp_read_server_font_map_pdu(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ boolean rdp_send_server_font_map_pdu(rdpRdp* rdp)
|
|||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_read_deactivate_all(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 lengthSourceDescriptor;
|
||||
|
||||
|
@ -250,7 +250,7 @@ boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s)
|
|||
{
|
||||
uint16 action;
|
||||
|
||||
if (!rdp_read_control_pdu(s, &action))
|
||||
if (!rdp_recv_control_pdu(s, &action))
|
||||
return False;
|
||||
if (action == CTRLACTION_REQUEST_CONTROL)
|
||||
{
|
||||
|
@ -262,7 +262,7 @@ boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!rdp_read_client_font_list_pdu(s))
|
||||
if (!rdp_recv_client_font_list_pdu(s))
|
||||
return False;
|
||||
if (!rdp_send_server_font_map_pdu(rdp))
|
||||
return False;
|
||||
|
|
|
@ -38,21 +38,21 @@
|
|||
#define FONTLIST_FIRST 0x0001
|
||||
#define FONTLIST_LAST 0x0002
|
||||
|
||||
boolean rdp_read_deactivate_all(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s);
|
||||
|
||||
boolean rdp_read_server_synchronize_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp);
|
||||
boolean rdp_read_client_synchronize_pdu(STREAM* s);
|
||||
boolean rdp_recv_client_synchronize_pdu(STREAM* s);
|
||||
boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp);
|
||||
boolean rdp_read_control_pdu(STREAM* s, uint16* action);
|
||||
boolean rdp_read_server_control_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_control_pdu(STREAM* s, uint16* action);
|
||||
boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp);
|
||||
boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp);
|
||||
boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action);
|
||||
boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp);
|
||||
boolean rdp_read_client_font_list_pdu(STREAM* s);
|
||||
boolean rdp_recv_client_font_list_pdu(STREAM* s);
|
||||
boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags);
|
||||
boolean rdp_read_server_font_map_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_send_server_font_map_pdu(rdpRdp* rdp);
|
||||
|
||||
boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s);
|
||||
|
|
|
@ -1576,7 +1576,7 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number
|
|||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_read_demand_active(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 channelId;
|
||||
|
@ -1676,7 +1676,7 @@ boolean rdp_send_demand_active(rdpRdp* rdp)
|
|||
return True;
|
||||
}
|
||||
|
||||
boolean rdp_read_confirm_active(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 channelId;
|
||||
|
|
|
@ -163,10 +163,10 @@
|
|||
#define CLW_ENTROPY_RLGR1 0x01
|
||||
#define CLW_ENTROPY_RLGR3 0x04
|
||||
|
||||
boolean rdp_read_demand_active(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s);
|
||||
void rdp_write_demand_active(STREAM* s, rdpSettings* settings);
|
||||
boolean rdp_send_demand_active(rdpRdp* rdp);
|
||||
boolean rdp_read_confirm_active(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_confirm_active(rdpRdp* rdp, STREAM* s);
|
||||
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings);
|
||||
boolean rdp_send_confirm_active(rdpRdp* rdp);
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ boolean rdp_client_connect(rdpRdp* rdp)
|
|||
|
||||
boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_read_connect_response(rdp->mcs, s))
|
||||
if (!mcs_recv_connect_response(rdp->mcs, s))
|
||||
return False;
|
||||
|
||||
if (!mcs_send_erect_domain_request(rdp->mcs))
|
||||
|
@ -121,7 +121,7 @@ boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_read_attach_user_confirm(rdp->mcs, s))
|
||||
if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
|
||||
return False;
|
||||
|
||||
if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->user_id))
|
||||
|
@ -138,7 +138,7 @@ boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s)
|
|||
uint16 channel_id;
|
||||
boolean all_joined = True;
|
||||
|
||||
if (!mcs_read_channel_join_confirm(rdp->mcs, s, &channel_id))
|
||||
if (!mcs_recv_channel_join_confirm(rdp->mcs, s, &channel_id))
|
||||
return False;
|
||||
|
||||
if (!rdp->mcs->user_channel_joined)
|
||||
|
@ -198,7 +198,7 @@ boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!license_read(rdp->license, s))
|
||||
if (!license_recv(rdp->license, s))
|
||||
return False;
|
||||
|
||||
if (rdp->license->state == LICENSE_STATE_ABORTED)
|
||||
|
@ -219,7 +219,7 @@ boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!rdp_read_demand_active(rdp, s))
|
||||
if (!rdp_recv_demand_active(rdp, s))
|
||||
return False;
|
||||
|
||||
if (!rdp_send_confirm_active(rdp))
|
||||
|
@ -315,7 +315,7 @@ boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!mcs_read_connect_initial(rdp->mcs, s))
|
||||
if (!mcs_recv_connect_initial(rdp->mcs, s))
|
||||
return False;
|
||||
|
||||
printf("Accepted client: %s\n", rdp->settings->client_hostname);
|
||||
|
@ -336,7 +336,7 @@ boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_read_erect_domain_request(rdp->mcs, s))
|
||||
if (!mcs_recv_erect_domain_request(rdp->mcs, s))
|
||||
return False;
|
||||
|
||||
rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
|
||||
|
@ -346,7 +346,7 @@ boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!mcs_read_attach_user_request(rdp->mcs, s))
|
||||
if (!mcs_recv_attach_user_request(rdp->mcs, s))
|
||||
return False;
|
||||
|
||||
if (!mcs_send_attach_user_confirm(rdp->mcs))
|
||||
|
@ -363,7 +363,7 @@ boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
|
|||
uint16 channel_id;
|
||||
boolean all_joined = True;
|
||||
|
||||
if (!mcs_read_channel_join_request(rdp->mcs, s, &channel_id))
|
||||
if (!mcs_recv_channel_join_request(rdp->mcs, s, &channel_id))
|
||||
return False;
|
||||
|
||||
if (!mcs_send_channel_join_confirm(rdp->mcs, channel_id))
|
||||
|
@ -391,7 +391,7 @@ boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!rdp_read_client_info(rdp, s))
|
||||
if (!rdp_recv_client_info(rdp, s))
|
||||
return False;
|
||||
|
||||
if (!license_send_valid_client_error_packet(rdp->license))
|
||||
|
@ -407,7 +407,7 @@ boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
|
|||
|
||||
boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (!rdp_read_confirm_active(rdp, s))
|
||||
if (!rdp_recv_confirm_active(rdp, s))
|
||||
return False;
|
||||
|
||||
rdp->state = CONNECTION_STATE_ACTIVE;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "orders.h"
|
||||
#include "update.h"
|
||||
#include "surface.h"
|
||||
|
||||
#include "fastpath.h"
|
||||
|
||||
|
@ -37,6 +38,8 @@
|
|||
* two less significant bits of the first byte.
|
||||
*/
|
||||
|
||||
#define FASTPATH_MAX_PACKET_SIZE 0x7FFF
|
||||
|
||||
/**
|
||||
* Read a Fast-Path packet header.\n
|
||||
* @param s stream
|
||||
|
@ -52,7 +55,10 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
|
|||
|
||||
stream_read_uint8(s, header);
|
||||
if (fastpath != NULL)
|
||||
{
|
||||
fastpath->encryptionFlags = (header & 0xC0) >> 6;
|
||||
fastpath->numberEvents = (header & 0x3C) >> 2;
|
||||
}
|
||||
|
||||
stream_read_uint8(s, length); /* length1 */
|
||||
/* If most significant bit is not set, length2 is not presented. */
|
||||
|
@ -67,69 +73,16 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
|
|||
return length;
|
||||
}
|
||||
|
||||
static int fastpath_recv_update_surfcmd_surface_bits(rdpFastPath* fastpath, STREAM* s)
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
|
||||
int pos;
|
||||
/* TODO: fipsInformation */
|
||||
|
||||
stream_read_uint16(s, cmd->destLeft);
|
||||
stream_read_uint16(s, cmd->destTop);
|
||||
stream_read_uint16(s, cmd->destRight);
|
||||
stream_read_uint16(s, cmd->destBottom);
|
||||
stream_read_uint8(s, cmd->bpp);
|
||||
stream_seek(s, 2); /* reserved1, reserved2 */
|
||||
stream_read_uint8(s, cmd->codecID);
|
||||
stream_read_uint16(s, cmd->width);
|
||||
stream_read_uint16(s, cmd->height);
|
||||
stream_read_uint32(s, cmd->bitmapDataLength);
|
||||
pos = stream_get_pos(s) + cmd->bitmapDataLength;
|
||||
cmd->bitmapData = stream_get_tail(s);
|
||||
|
||||
IFCALL(update->SurfaceBits, update, cmd);
|
||||
|
||||
stream_set_pos(s, pos);
|
||||
|
||||
return 20 + cmd->bitmapDataLength;
|
||||
}
|
||||
|
||||
static int fastpath_recv_update_surfcmd_frame_marker(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint16 frameAction;
|
||||
uint32 frameId;
|
||||
|
||||
stream_read_uint16(s, frameAction);
|
||||
stream_read_uint32(s, frameId);
|
||||
/*printf("frameAction %d frameId %d\n", frameAction, frameId);*/
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
static void fastpath_recv_update_surfcmds(rdpFastPath* fastpath, uint16 size, STREAM* s)
|
||||
{
|
||||
uint16 cmdType;
|
||||
|
||||
while (size > 2)
|
||||
if ((fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED))
|
||||
{
|
||||
stream_read_uint16(s, cmdType);
|
||||
size -= 2;
|
||||
|
||||
switch (cmdType)
|
||||
{
|
||||
case CMDTYPE_SET_SURFACE_BITS:
|
||||
case CMDTYPE_STREAM_SURFACE_BITS:
|
||||
size -= fastpath_recv_update_surfcmd_surface_bits(fastpath, s);
|
||||
break;
|
||||
|
||||
case CMDTYPE_FRAME_MARKER:
|
||||
size -= fastpath_recv_update_surfcmd_frame_marker(fastpath, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unknown cmdType 0x%X", cmdType);
|
||||
return;
|
||||
}
|
||||
stream_seek(s, 8); /* dataSignature */
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void fastpath_recv_orders(rdpFastPath* fastpath, STREAM* s)
|
||||
|
@ -187,7 +140,7 @@ static void fastpath_recv_update(rdpFastPath* fastpath, uint8 updateCode, uint16
|
|||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_SURFCMDS:
|
||||
fastpath_recv_update_surfcmds(fastpath, size, s);
|
||||
update_recv_surfcmds(fastpath->rdp->update, size, s);
|
||||
break;
|
||||
|
||||
case FASTPATH_UPDATETYPE_PTR_NULL:
|
||||
|
@ -278,7 +231,7 @@ static void fastpath_recv_update_data(rdpFastPath* fastpath, STREAM* s)
|
|||
stream_set_pos(s, next_pos);
|
||||
}
|
||||
|
||||
void fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
rdpUpdate* update = fastpath->rdp->update;
|
||||
|
||||
|
@ -290,34 +243,288 @@ void fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s)
|
|||
}
|
||||
|
||||
IFCALL(update->EndPaint, update);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath)
|
||||
static boolean fastpath_read_input_event_header(STREAM* s, uint8* eventFlags, uint8* eventCode)
|
||||
{
|
||||
uint8 eventHeader;
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, eventHeader); /* eventHeader (1 byte) */
|
||||
|
||||
*eventFlags = (eventHeader & 0x1F);
|
||||
*eventCode = (eventHeader >> 5);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_scancode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 flags;
|
||||
uint16 code;
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, code); /* keyCode (1 byte) */
|
||||
|
||||
flags = 0;
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
|
||||
flags |= KBD_FLAGS_RELEASE;
|
||||
else
|
||||
flags |= KBD_FLAGS_DOWN;
|
||||
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
|
||||
flags |= KBD_FLAGS_EXTENDED;
|
||||
|
||||
IFCALL(fastpath->rdp->input->KeyboardEvent, fastpath->rdp->input, flags, code);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_mouse(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 pointerFlags;
|
||||
uint16 xPos;
|
||||
uint16 yPos;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return False;
|
||||
|
||||
stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
stream_read_uint16(s, xPos); /* xPos (2 bytes) */
|
||||
stream_read_uint16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(fastpath->rdp->input->MouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_mousex(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 pointerFlags;
|
||||
uint16 xPos;
|
||||
uint16 yPos;
|
||||
|
||||
if (stream_get_left(s) < 6)
|
||||
return False;
|
||||
|
||||
stream_read_uint16(s, pointerFlags); /* pointerFlags (2 bytes) */
|
||||
stream_read_uint16(s, xPos); /* xPos (2 bytes) */
|
||||
stream_read_uint16(s, yPos); /* yPos (2 bytes) */
|
||||
|
||||
IFCALL(fastpath->rdp->input->ExtendedMouseEvent, fastpath->rdp->input, pointerFlags, xPos, yPos);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_sync(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
IFCALL(fastpath->rdp->input->SynchronizeEvent, fastpath->rdp->input, eventFlags);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event_unicode(rdpFastPath* fastpath, STREAM* s, uint8 eventFlags)
|
||||
{
|
||||
uint16 unicodeCode;
|
||||
|
||||
if (stream_get_left(s) < 2)
|
||||
return False;
|
||||
|
||||
stream_read_uint16(s, unicodeCode); /* unicodeCode (2 bytes) */
|
||||
|
||||
IFCALL(fastpath->rdp->input->UnicodeKeyboardEvent, fastpath->rdp->input, unicodeCode);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static boolean fastpath_recv_input_event(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 eventFlags;
|
||||
uint8 eventCode;
|
||||
|
||||
if (!fastpath_read_input_event_header(s, &eventFlags, &eventCode))
|
||||
return False;
|
||||
|
||||
switch (eventCode)
|
||||
{
|
||||
case FASTPATH_INPUT_EVENT_SCANCODE:
|
||||
if (!fastpath_recv_input_event_scancode(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSE:
|
||||
if (!fastpath_recv_input_event_mouse(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_MOUSEX:
|
||||
if (!fastpath_recv_input_event_mousex(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_SYNC:
|
||||
if (!fastpath_recv_input_event_sync(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case FASTPATH_INPUT_EVENT_UNICODE:
|
||||
if (!fastpath_recv_input_event_unicode(fastpath, s, eventFlags))
|
||||
return False;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown eventCode %d\n", eventCode);
|
||||
break;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
uint8 i;
|
||||
|
||||
if (fastpath->numberEvents == 0)
|
||||
{
|
||||
/**
|
||||
* If numberEvents is not provided in fpInputHeader, it will be provided
|
||||
* as onee additional byte here.
|
||||
*/
|
||||
|
||||
if (stream_get_left(s) < 1)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, fastpath->numberEvents); /* eventHeader (1 byte) */
|
||||
}
|
||||
|
||||
for (i = 0; i < fastpath->numberEvents; i++)
|
||||
{
|
||||
if (!fastpath_recv_input_event(fastpath, s))
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode)
|
||||
{
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(fastpath->rdp->transport, 127);
|
||||
stream_seek(s, 2); /* fpInputHeader and length1 */
|
||||
/* length2 is not necessary since input PDU should not exceed 127 bytes */
|
||||
stream_write_uint8(s, eventFlags | (eventCode << 5)); /* eventHeader (1 byte) */
|
||||
return s;
|
||||
}
|
||||
|
||||
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents)
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s)
|
||||
{
|
||||
int length;
|
||||
uint16 length;
|
||||
|
||||
length = stream_get_length(s);
|
||||
if (length > 127)
|
||||
{
|
||||
printf("Maximum FastPath PDU length is 127\n");
|
||||
return;
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_set_pos(s, 0);
|
||||
stream_write_uint8(s, (numberEvents << 2));
|
||||
stream_write_uint8(s, (1 << 2));
|
||||
stream_write_uint8(s, length);
|
||||
|
||||
stream_set_pos(s, length);
|
||||
transport_write(fastpath->rdp->transport, s);
|
||||
if (transport_write(fastpath->rdp->transport, s) < 0)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath)
|
||||
{
|
||||
STREAM* s;
|
||||
s = transport_send_stream_init(fastpath->rdp->transport, FASTPATH_MAX_PACKET_SIZE);
|
||||
stream_seek(s, 3); /* fpOutputHeader, length1 and length2 */
|
||||
return s;
|
||||
}
|
||||
|
||||
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);
|
||||
return False;
|
||||
}
|
||||
|
||||
stream_set_pos(s, 0);
|
||||
stream_write_uint8(s, 0); /* fpOutputHeader (1 byte) */
|
||||
stream_write_uint8(s, 0x80 | (length >> 8)); /* length1 */
|
||||
stream_write_uint8(s, length & 0xFF); /* length2 */
|
||||
|
||||
stream_set_pos(s, length);
|
||||
if (transport_write(fastpath->rdp->transport, s) < 0)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean fastpath_send_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
STREAM* s;
|
||||
uint16 size;
|
||||
uint8* bitmapData;
|
||||
uint32 bitmapDataLength;
|
||||
uint16 fragment_size;
|
||||
uint8 fragmentation;
|
||||
int i;
|
||||
int bp, ep;
|
||||
|
||||
bitmapData = cmd->bitmapData;
|
||||
bitmapDataLength = cmd->bitmapDataLength;
|
||||
for (i = 0; bitmapDataLength > 0; i++)
|
||||
{
|
||||
s = fastpath_update_pdu_init(fastpath);
|
||||
|
||||
bp = stream_get_pos(s);
|
||||
stream_seek_uint8(s); /* updateHeader (1 byte) */
|
||||
stream_seek_uint16(s); /* size (2 bytes) */
|
||||
size = 0;
|
||||
|
||||
if (i == 0)
|
||||
size += update_write_surfcmd_surface_bits_header(s, cmd);
|
||||
|
||||
fragment_size = MIN(stream_get_left(s), bitmapDataLength);
|
||||
if (fragment_size == bitmapDataLength)
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentation = (i == 0 ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT);
|
||||
}
|
||||
size += fragment_size;
|
||||
|
||||
ep = stream_get_pos(s);
|
||||
stream_set_pos(s, bp);
|
||||
stream_write_uint8(s, FASTPATH_UPDATETYPE_SURFCMDS | (fragmentation << 4));
|
||||
stream_write_uint16(s, size);
|
||||
stream_set_pos(s, ep);
|
||||
|
||||
stream_write(s, bitmapData, fragment_size);
|
||||
bitmapData += fragment_size;
|
||||
bitmapDataLength -= fragment_size;
|
||||
|
||||
if (!fastpath_send_update_pdu(fastpath, s))
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp)
|
||||
|
|
|
@ -72,18 +72,43 @@ enum FASTPATH_OUTPUT_COMPRESSION
|
|||
FASTPATH_OUTPUT_COMPRESSION_USED = 0x2
|
||||
};
|
||||
|
||||
/* FastPath Input Events */
|
||||
enum FASTPATH_INPUT_EVENT_CODE
|
||||
{
|
||||
FASTPATH_INPUT_EVENT_SCANCODE = 0x0,
|
||||
FASTPATH_INPUT_EVENT_MOUSE = 0x1,
|
||||
FASTPATH_INPUT_EVENT_MOUSEX = 0x2,
|
||||
FASTPATH_INPUT_EVENT_SYNC = 0x3,
|
||||
FASTPATH_INPUT_EVENT_UNICODE = 0x4
|
||||
};
|
||||
|
||||
/* FastPath Keyboard Event Flags */
|
||||
enum FASTPATH_INPUT_KBDFLAGS
|
||||
{
|
||||
FASTPATH_INPUT_KBDFLAGS_RELEASE = 0x01,
|
||||
FASTPATH_INPUT_KBDFLAGS_EXTENDED = 0x02
|
||||
};
|
||||
|
||||
struct rdp_fastpath
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
uint8 encryptionFlags;
|
||||
uint8 numberEvents;
|
||||
STREAM* updateData;
|
||||
};
|
||||
|
||||
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
|
||||
void fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
|
||||
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_pdu_init(rdpFastPath* fastpath);
|
||||
void fastpath_send_pdu(rdpFastPath* fastpath, STREAM* s, uint8 numberEvents);
|
||||
STREAM* fastpath_input_pdu_init(rdpFastPath* fastpath, uint8 eventFlags, uint8 eventCode);
|
||||
boolean fastpath_send_input_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath);
|
||||
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, STREAM* s);
|
||||
|
||||
boolean fastpath_send_surface_bits(rdpFastPath* fastpath, SURFACE_BITS_COMMAND* cmd);
|
||||
|
||||
rdpFastPath* fastpath_new(rdpRdp* rdp);
|
||||
void fastpath_free(rdpFastPath* fastpath);
|
||||
|
|
|
@ -88,6 +88,8 @@ freerdp* freerdp_new()
|
|||
instance->GetFileDescriptor = freerdp_get_fds;
|
||||
instance->CheckFileDescriptor = freerdp_check_fds;
|
||||
instance->SendChannelData = freerdp_send_channel_data;
|
||||
|
||||
input_register_client_callbacks(rdp->input);
|
||||
}
|
||||
|
||||
return instance;
|
||||
|
|
|
@ -556,7 +556,7 @@ void rdp_write_info_packet(STREAM* s, rdpSettings* settings)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean rdp_read_client_info(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 channelId;
|
||||
|
@ -654,7 +654,7 @@ void rdp_recv_logon_info_extended(rdpRdp* rdp, STREAM* s)
|
|||
stream_seek(s, 570); /* pad */
|
||||
}
|
||||
|
||||
boolean rdp_read_save_session_info(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint32 infoType;
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ boolean rdp_read_extended_info_packet(STREAM* s, rdpSettings* settings);
|
|||
void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings);
|
||||
boolean rdp_read_info_packet(STREAM* s, rdpSettings* settings);
|
||||
void rdp_write_info_packet(STREAM* s, rdpSettings* settings);
|
||||
boolean rdp_read_client_info(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_client_info(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_send_client_info(rdpRdp* rdp);
|
||||
boolean rdp_read_save_session_info(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s);
|
||||
|
||||
#endif /* __INFO_H */
|
||||
|
|
|
@ -119,60 +119,79 @@ void input_send_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, ui
|
|||
rdp_send_client_input_pdu(input->rdp, s);
|
||||
}
|
||||
|
||||
STREAM* rdp_client_fastpath_input_pdu_init(rdpRdp* rdp, uint8 flags, uint8 code)
|
||||
{
|
||||
STREAM* s;
|
||||
s = fastpath_pdu_init(rdp->fastpath);
|
||||
stream_write_uint8(s, flags | (code << 5)); /* eventHeader */
|
||||
return s;
|
||||
}
|
||||
|
||||
void rdp_send_client_fastpath_input_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
fastpath_send_pdu(rdp->fastpath, s, 1);
|
||||
}
|
||||
|
||||
void input_send_fastpath_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
|
||||
/* The FastPath Synchronization eventFlags has identical values as SlowPath */
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, (uint8)flags, FASTPATH_INPUT_EVENT_SYNC);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
uint8 eventFlags = 0;
|
||||
|
||||
eventFlags |= (flags & KBD_FLAGS_RELEASE) ? FASTPATH_INPUT_KBDFLAGS_RELEASE : 0;
|
||||
eventFlags |= (flags & KBD_FLAGS_EXTENDED) ? FASTPATH_INPUT_KBDFLAGS_EXTENDED : 0;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, eventFlags, FASTPATH_INPUT_EVENT_SCANCODE);
|
||||
stream_write_uint8(s, code); /* keyCode (1 byte) */
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_UNICODE);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_UNICODE);
|
||||
stream_write_uint16(s, code); /* unicodeCode (2 bytes) */
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSE);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSE);
|
||||
input_write_mouse_event(s, flags, x, y);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
STREAM* s;
|
||||
s = rdp_client_fastpath_input_pdu_init(input->rdp, 0, FASTPATH_INPUT_EVENT_MOUSEX);
|
||||
|
||||
s = fastpath_input_pdu_init(rdp->fastpath, 0, FASTPATH_INPUT_EVENT_MOUSEX);
|
||||
input_write_extended_mouse_event(s, flags, x, y);
|
||||
rdp_send_client_fastpath_input_pdu(input->rdp, s);
|
||||
fastpath_send_input_pdu(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
void input_register_client_callbacks(rdpInput* input)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)input->rdp;
|
||||
|
||||
if (rdp->settings->fastpath_input)
|
||||
{
|
||||
input->SynchronizeEvent = input_send_fastpath_synchronize_event;
|
||||
input->KeyboardEvent = input_send_fastpath_keyboard_event;
|
||||
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
|
||||
input->MouseEvent = input_send_fastpath_mouse_event;
|
||||
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
|
||||
}
|
||||
else
|
||||
{
|
||||
input->SynchronizeEvent = input_send_synchronize_event;
|
||||
input->KeyboardEvent = input_send_keyboard_event;
|
||||
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
|
||||
input->MouseEvent = input_send_mouse_event;
|
||||
input->ExtendedMouseEvent = input_send_extended_mouse_event;
|
||||
}
|
||||
}
|
||||
|
||||
rdpInput* input_new(rdpRdp* rdp)
|
||||
|
@ -184,22 +203,6 @@ rdpInput* input_new(rdpRdp* rdp)
|
|||
if (input != NULL)
|
||||
{
|
||||
input->rdp = rdp;
|
||||
if (rdp->settings->fastpath_input)
|
||||
{
|
||||
input->SynchronizeEvent = input_send_fastpath_synchronize_event;
|
||||
input->KeyboardEvent = input_send_fastpath_keyboard_event;
|
||||
input->UnicodeKeyboardEvent = input_send_fastpath_unicode_keyboard_event;
|
||||
input->MouseEvent = input_send_fastpath_mouse_event;
|
||||
input->ExtendedMouseEvent = input_send_fastpath_extended_mouse_event;
|
||||
}
|
||||
else
|
||||
{
|
||||
input->SynchronizeEvent = input_send_synchronize_event;
|
||||
input->KeyboardEvent = input_send_keyboard_event;
|
||||
input->UnicodeKeyboardEvent = input_send_unicode_keyboard_event;
|
||||
input->MouseEvent = input_send_mouse_event;
|
||||
input->ExtendedMouseEvent = input_send_extended_mouse_event;
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
|
|
|
@ -35,17 +35,6 @@
|
|||
#define INPUT_EVENT_MOUSE 0x8001
|
||||
#define INPUT_EVENT_MOUSEX 0x8002
|
||||
|
||||
/* FastPath Input Events */
|
||||
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
|
||||
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
|
||||
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
|
||||
#define FASTPATH_INPUT_EVENT_SYNC 0x3
|
||||
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
|
||||
|
||||
/* FastPath Keyboard Event Flags */
|
||||
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
|
||||
|
||||
#define RDP_CLIENT_INPUT_PDU_HEADER_LENGTH 4
|
||||
|
||||
void input_send_synchronize_event(rdpInput* input, uint32 flags);
|
||||
|
@ -60,6 +49,8 @@ void input_send_fastpath_unicode_keyboard_event(rdpInput* input, uint16 code);
|
|||
void input_send_fastpath_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
|
||||
void input_send_fastpath_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y);
|
||||
|
||||
void input_register_client_callbacks(rdpInput* input);
|
||||
|
||||
rdpInput* input_new(rdpRdp* rdp);
|
||||
void input_free(rdpInput* input);
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ boolean license_send(rdpLicense* license, STREAM* s, uint8 type)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean license_read(rdpLicense* license, STREAM* s)
|
||||
boolean license_recv(rdpLicense* license, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 channelId;
|
||||
|
|
|
@ -156,7 +156,7 @@ struct rdp_license
|
|||
SCOPE_LIST* scope_list;
|
||||
};
|
||||
|
||||
boolean license_read(rdpLicense* license, STREAM* s);
|
||||
boolean license_recv(rdpLicense* license, STREAM* s);
|
||||
boolean license_send(rdpLicense* license, STREAM* s, uint8 type);
|
||||
STREAM* license_send_stream_init(rdpLicense* license);
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ void mcs_print_domain_parameters(DomainParameters* domainParameters)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean mcs_read_connect_initial(rdpMcs* mcs, STREAM* s)
|
||||
boolean mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s)
|
||||
{
|
||||
int length;
|
||||
boolean upwardFlag;
|
||||
|
@ -496,7 +496,7 @@ boolean mcs_send_connect_initial(rdpMcs* mcs)
|
|||
* @param mcs mcs module
|
||||
*/
|
||||
|
||||
boolean mcs_read_connect_response(rdpMcs* mcs, STREAM* s)
|
||||
boolean mcs_recv_connect_response(rdpMcs* mcs, STREAM* s)
|
||||
{
|
||||
int length;
|
||||
uint8 result;
|
||||
|
@ -571,7 +571,7 @@ boolean mcs_send_connect_response(rdpMcs* mcs)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s)
|
||||
boolean mcs_recv_erect_domain_request(rdpMcs* mcs, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
@ -613,7 +613,7 @@ boolean mcs_send_erect_domain_request(rdpMcs* mcs)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s)
|
||||
boolean mcs_recv_attach_user_request(rdpMcs* mcs, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
@ -651,7 +651,7 @@ boolean mcs_send_attach_user_request(rdpMcs* mcs)
|
|||
* @param mcs mcs module
|
||||
*/
|
||||
|
||||
boolean mcs_read_attach_user_confirm(rdpMcs* mcs, STREAM* s)
|
||||
boolean mcs_recv_attach_user_confirm(rdpMcs* mcs, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint8 result;
|
||||
|
@ -698,7 +698,7 @@ boolean mcs_send_attach_user_confirm(rdpMcs* mcs)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id)
|
||||
boolean mcs_recv_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id)
|
||||
{
|
||||
uint16 length;
|
||||
enum DomainMCSPDU MCSPDU;
|
||||
|
@ -748,7 +748,7 @@ boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id)
|
|||
* @param mcs mcs module
|
||||
*/
|
||||
|
||||
boolean mcs_read_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id)
|
||||
boolean mcs_recv_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id)
|
||||
{
|
||||
uint16 length;
|
||||
uint8 result;
|
||||
|
|
|
@ -132,19 +132,19 @@ typedef struct rdp_mcs rdpMcs;
|
|||
void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data);
|
||||
void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data);
|
||||
|
||||
boolean mcs_read_connect_initial(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_recv_connect_initial(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_send_connect_initial(rdpMcs* mcs);
|
||||
boolean mcs_read_connect_response(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_recv_connect_response(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_send_connect_response(rdpMcs* mcs);
|
||||
boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_recv_erect_domain_request(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_send_erect_domain_request(rdpMcs* mcs);
|
||||
boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_recv_attach_user_request(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_send_attach_user_request(rdpMcs* mcs);
|
||||
boolean mcs_read_attach_user_confirm(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_recv_attach_user_confirm(rdpMcs* mcs, STREAM* s);
|
||||
boolean mcs_send_attach_user_confirm(rdpMcs* mcs);
|
||||
boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id);
|
||||
boolean mcs_recv_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id);
|
||||
boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id);
|
||||
boolean mcs_read_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id);
|
||||
boolean mcs_recv_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id);
|
||||
boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id);
|
||||
boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, uint16* length);
|
||||
void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, uint16 length, uint8 options);
|
||||
|
|
|
@ -54,7 +54,7 @@ static boolean freerdp_peer_check_fds(freerdp_peer* client)
|
|||
return True;
|
||||
}
|
||||
|
||||
static boolean peer_read_data_pdu(rdpPeer* peer, STREAM* s)
|
||||
static boolean peer_recv_data_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
uint8 type;
|
||||
uint16 length;
|
||||
|
@ -66,7 +66,7 @@ static boolean peer_read_data_pdu(rdpPeer* peer, STREAM* s)
|
|||
switch (type)
|
||||
{
|
||||
case DATA_PDU_TYPE_SYNCHRONIZE:
|
||||
if (!rdp_read_client_synchronize_pdu(s))
|
||||
if (!rdp_recv_client_synchronize_pdu(s))
|
||||
return False;
|
||||
break;
|
||||
|
||||
|
@ -82,6 +82,11 @@ static boolean peer_read_data_pdu(rdpPeer* peer, STREAM* s)
|
|||
case DATA_PDU_TYPE_FONT_LIST:
|
||||
if (!rdp_server_accept_client_font_list_pdu(peer->rdp, s))
|
||||
return False;
|
||||
if (peer->client->PostConnect)
|
||||
{
|
||||
if (!peer->client->PostConnect(peer->client))
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -92,7 +97,7 @@ static boolean peer_read_data_pdu(rdpPeer* peer, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
static boolean peer_read_tpkt_pdu(rdpPeer* peer, STREAM* s)
|
||||
static boolean peer_recv_tpkt_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 pduType;
|
||||
|
@ -117,7 +122,7 @@ static boolean peer_read_tpkt_pdu(rdpPeer* peer, STREAM* s)
|
|||
switch (pduType)
|
||||
{
|
||||
case PDU_TYPE_DATA:
|
||||
if (!peer_read_data_pdu(peer, s))
|
||||
if (!peer_recv_data_pdu(peer, s))
|
||||
return False;
|
||||
break;
|
||||
|
||||
|
@ -130,18 +135,29 @@ static boolean peer_read_tpkt_pdu(rdpPeer* peer, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
static boolean peer_read_fastpath_pdu(rdpPeer* peer, STREAM* s)
|
||||
static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
printf("FastPath Input PDU\n");
|
||||
return True;
|
||||
uint16 length;
|
||||
|
||||
length = fastpath_read_header(peer->rdp->fastpath, s);
|
||||
if (length == 0 || length > stream_get_size(s))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!fastpath_read_security_header(peer->rdp->fastpath, s))
|
||||
return False;
|
||||
|
||||
return fastpath_recv_inputs(peer->rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static boolean peer_read_pdu(rdpPeer* peer, STREAM* s)
|
||||
static boolean peer_recv_pdu(rdpPeer* peer, STREAM* s)
|
||||
{
|
||||
if (tpkt_verify_header(s))
|
||||
return peer_read_tpkt_pdu(peer, s);
|
||||
return peer_recv_tpkt_pdu(peer, s);
|
||||
else
|
||||
return peer_read_fastpath_pdu(peer, s);
|
||||
return peer_recv_fastpath_pdu(peer, s);
|
||||
}
|
||||
|
||||
static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
@ -186,7 +202,7 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
|||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
if (!peer_read_pdu(peer, s))
|
||||
if (!peer_recv_pdu(peer, s))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
|
@ -200,6 +216,9 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
|||
|
||||
static void freerdp_peer_disconnect(freerdp_peer* client)
|
||||
{
|
||||
rdpPeer* peer = (rdpPeer*)client->peer;
|
||||
|
||||
transport_disconnect(peer->rdp->transport);
|
||||
}
|
||||
|
||||
freerdp_peer* freerdp_peer_new(int sockfd)
|
||||
|
@ -220,6 +239,10 @@ freerdp_peer* freerdp_peer_new(int sockfd)
|
|||
|
||||
client->peer = (void*)peer;
|
||||
client->settings = peer->rdp->settings;
|
||||
client->input = peer->rdp->input;
|
||||
client->update = peer->rdp->update;
|
||||
|
||||
update_register_server_callbacks(client->update);
|
||||
|
||||
transport_attach(peer->rdp->transport, sockfd);
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id)
|
|||
return True;
|
||||
}
|
||||
|
||||
void rdp_read_set_error_info_data_pdu(STREAM* s)
|
||||
void rdp_recv_set_error_info_data_pdu(STREAM* s)
|
||||
{
|
||||
uint32 errorInfo;
|
||||
|
||||
|
@ -298,7 +298,7 @@ void rdp_read_set_error_info_data_pdu(STREAM* s)
|
|||
rdp_print_errinfo(errorInfo);
|
||||
}
|
||||
|
||||
void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint8 type;
|
||||
uint16 length;
|
||||
|
@ -316,7 +316,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
|||
break;
|
||||
|
||||
case DATA_PDU_TYPE_CONTROL:
|
||||
rdp_read_server_control_pdu(rdp, s);
|
||||
rdp_recv_server_control_pdu(rdp, s);
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_POINTER:
|
||||
|
@ -326,7 +326,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
|||
break;
|
||||
|
||||
case DATA_PDU_TYPE_SYNCHRONIZE:
|
||||
rdp_read_server_synchronize_pdu(rdp, s);
|
||||
rdp_recv_server_synchronize_pdu(rdp, s);
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_REFRESH_RECT:
|
||||
|
@ -345,14 +345,14 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
|||
break;
|
||||
|
||||
case DATA_PDU_TYPE_SAVE_SESSION_INFO:
|
||||
rdp_read_save_session_info(rdp, s);
|
||||
rdp_recv_save_session_info(rdp, s);
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_FONT_LIST:
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_FONT_MAP:
|
||||
rdp_read_server_font_map_pdu(rdp, s);
|
||||
rdp_recv_server_font_map_pdu(rdp, s);
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
|
||||
|
@ -371,7 +371,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
|||
break;
|
||||
|
||||
case DATA_PDU_TYPE_SET_ERROR_INFO:
|
||||
rdp_read_set_error_info_data_pdu(s);
|
||||
rdp_recv_set_error_info_data_pdu(s);
|
||||
break;
|
||||
|
||||
case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
|
||||
|
@ -400,7 +400,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s)
|
|||
* @param s stream
|
||||
*/
|
||||
|
||||
static boolean rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
uint16 pduType;
|
||||
|
@ -424,16 +424,16 @@ static boolean rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
|||
switch (pduType)
|
||||
{
|
||||
case PDU_TYPE_DATA:
|
||||
rdp_read_data_pdu(rdp, s);
|
||||
rdp_recv_data_pdu(rdp, s);
|
||||
break;
|
||||
|
||||
case PDU_TYPE_DEACTIVATE_ALL:
|
||||
if (!rdp_read_deactivate_all(rdp, s))
|
||||
if (!rdp_recv_deactivate_all(rdp, s))
|
||||
return False;
|
||||
break;
|
||||
|
||||
case PDU_TYPE_SERVER_REDIRECTION:
|
||||
rdp_read_enhanced_security_redirection_packet(rdp, s);
|
||||
rdp_recv_enhanced_security_redirection_packet(rdp, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -445,35 +445,29 @@ static boolean rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
|||
return True;
|
||||
}
|
||||
|
||||
static boolean rdp_read_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static boolean rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
uint16 length;
|
||||
|
||||
length = fastpath_read_header(rdp->fastpath, s);
|
||||
if (length > stream_get_size(s))
|
||||
if (length == 0 || length > stream_get_size(s))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* TODO: fipsInformation */
|
||||
if (!fastpath_read_security_header(rdp->fastpath, s))
|
||||
return False;
|
||||
|
||||
if ((rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED))
|
||||
{
|
||||
stream_seek(s, 8); /* dataSignature */
|
||||
}
|
||||
|
||||
fastpath_recv_updates(rdp->fastpath, s);
|
||||
|
||||
return True;
|
||||
return fastpath_recv_updates(rdp->fastpath, s);
|
||||
}
|
||||
|
||||
static boolean rdp_read_pdu(rdpRdp* rdp, STREAM* s)
|
||||
static boolean rdp_recv_pdu(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
if (tpkt_verify_header(s))
|
||||
return rdp_read_tpkt_pdu(rdp, s);
|
||||
return rdp_recv_tpkt_pdu(rdp, s);
|
||||
else
|
||||
return rdp_read_fastpath_pdu(rdp, s);
|
||||
return rdp_recv_fastpath_pdu(rdp, s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -488,7 +482,7 @@ void rdp_recv(rdpRdp* rdp)
|
|||
s = transport_recv_stream_init(rdp->transport, 4096);
|
||||
transport_read(rdp->transport, s);
|
||||
|
||||
rdp_read_pdu(rdp, s);
|
||||
rdp_recv_pdu(rdp, s);
|
||||
}
|
||||
|
||||
static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
||||
|
@ -523,7 +517,7 @@ static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
|
|||
break;
|
||||
|
||||
case CONNECTION_STATE_ACTIVE:
|
||||
if (!rdp_read_pdu(rdp, s))
|
||||
if (!rdp_recv_pdu(rdp, s))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
|
|
|
@ -27,13 +27,17 @@
|
|||
* @param sec_flags security flags
|
||||
*/
|
||||
|
||||
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
printf("Redirection Packet\n");
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
void rdp_read_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s)
|
||||
boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s)
|
||||
{
|
||||
printf("Enhanced Security Redirection Packet\n");
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
void rdp_read_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s);
|
||||
|
||||
#endif /* __REDIRECTION_H */
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Surface Commands
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "surface.h"
|
||||
|
||||
static int update_recv_surfcmd_surface_bits(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
|
||||
int pos;
|
||||
|
||||
stream_read_uint16(s, cmd->destLeft);
|
||||
stream_read_uint16(s, cmd->destTop);
|
||||
stream_read_uint16(s, cmd->destRight);
|
||||
stream_read_uint16(s, cmd->destBottom);
|
||||
stream_read_uint8(s, cmd->bpp);
|
||||
stream_seek(s, 2); /* reserved1, reserved2 */
|
||||
stream_read_uint8(s, cmd->codecID);
|
||||
stream_read_uint16(s, cmd->width);
|
||||
stream_read_uint16(s, cmd->height);
|
||||
stream_read_uint32(s, cmd->bitmapDataLength);
|
||||
pos = stream_get_pos(s) + cmd->bitmapDataLength;
|
||||
cmd->bitmapData = stream_get_tail(s);
|
||||
|
||||
IFCALL(update->SurfaceBits, update, cmd);
|
||||
|
||||
stream_set_pos(s, pos);
|
||||
|
||||
return 20 + cmd->bitmapDataLength;
|
||||
}
|
||||
|
||||
static int update_recv_surfcmd_frame_marker(rdpUpdate* update, STREAM* s)
|
||||
{
|
||||
uint16 frameAction;
|
||||
uint32 frameId;
|
||||
|
||||
stream_read_uint16(s, frameAction);
|
||||
stream_read_uint32(s, frameId);
|
||||
/*printf("frameAction %d frameId %d\n", frameAction, frameId);*/
|
||||
|
||||
return 6;
|
||||
}
|
||||
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s)
|
||||
{
|
||||
uint16 cmdType;
|
||||
|
||||
while (size > 2)
|
||||
{
|
||||
stream_read_uint16(s, cmdType);
|
||||
size -= 2;
|
||||
|
||||
switch (cmdType)
|
||||
{
|
||||
case CMDTYPE_SET_SURFACE_BITS:
|
||||
case CMDTYPE_STREAM_SURFACE_BITS:
|
||||
size -= update_recv_surfcmd_surface_bits(update, s);
|
||||
break;
|
||||
|
||||
case CMDTYPE_FRAME_MARKER:
|
||||
size -= update_recv_surfcmd_frame_marker(update, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_WARN("unknown cmdType 0x%X", cmdType);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
int update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd)
|
||||
{
|
||||
stream_check_size(s, 22);
|
||||
|
||||
stream_write_uint16(s, CMDTYPE_STREAM_SURFACE_BITS);
|
||||
|
||||
stream_write_uint16(s, cmd->destLeft);
|
||||
stream_write_uint16(s, cmd->destTop);
|
||||
stream_write_uint16(s, cmd->destRight);
|
||||
stream_write_uint16(s, cmd->destBottom);
|
||||
stream_write_uint8(s, cmd->bpp);
|
||||
stream_write_uint16(s, 0); /* reserved1, reserved2 */
|
||||
stream_write_uint8(s, cmd->codecID);
|
||||
stream_write_uint16(s, cmd->width);
|
||||
stream_write_uint16(s, cmd->height);
|
||||
stream_write_uint32(s, cmd->bitmapDataLength);
|
||||
|
||||
return 22;
|
||||
}
|
||||
|
||||
int update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId)
|
||||
{
|
||||
stream_check_size(s, 8);
|
||||
|
||||
stream_write_uint16(s, CMDTYPE_FRAME_MARKER);
|
||||
|
||||
stream_write_uint16(s, frameAction);
|
||||
stream_write_uint32(s, frameId);
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* Surface Commands
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __SURFACE
|
||||
#define __SURFACE
|
||||
|
||||
#include "rdp.h"
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
boolean update_recv_surfcmds(rdpUpdate* update, uint16 size, STREAM* s);
|
||||
|
||||
int update_write_surfcmd_surface_bits_header(STREAM* s, SURFACE_BITS_COMMAND* cmd);
|
||||
int update_write_surfcmd_frame_marker(STREAM* s, uint16 frameAction, uint32 frameId);
|
||||
|
||||
#endif /* __SURFACE */
|
||||
|
|
@ -70,6 +70,8 @@ void transport_attach(rdpTransport* transport, int sockfd)
|
|||
|
||||
boolean transport_disconnect(rdpTransport* transport)
|
||||
{
|
||||
if (transport->tls)
|
||||
IFCALL(transport->tls->disconnect, transport->tls);
|
||||
return transport->tcp->disconnect(transport->tcp);
|
||||
}
|
||||
|
||||
|
@ -293,15 +295,27 @@ int transport_check_fds(rdpTransport* transport)
|
|||
|
||||
while ((pos = stream_get_pos(transport->recv_buffer)) > 0)
|
||||
{
|
||||
/* Ensure the TPKT or Fast Path header is available. */
|
||||
if (pos <= 4)
|
||||
return 0;
|
||||
|
||||
stream_set_pos(transport->recv_buffer, 0);
|
||||
if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */
|
||||
{
|
||||
/* Ensure the TPKT header is available. */
|
||||
if (pos <= 4)
|
||||
{
|
||||
stream_set_pos(transport->recv_buffer, pos);
|
||||
return 0;
|
||||
}
|
||||
length = tpkt_read_header(transport->recv_buffer);
|
||||
}
|
||||
else /* Fast Path */
|
||||
{
|
||||
/* Ensure the Fast Path header is available. */
|
||||
if (pos <= 2)
|
||||
{
|
||||
stream_set_pos(transport->recv_buffer, pos);
|
||||
return 0;
|
||||
}
|
||||
length = fastpath_read_header(NULL, transport->recv_buffer);
|
||||
}
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
|
@ -391,6 +405,8 @@ void transport_free(rdpTransport* transport)
|
|||
stream_free(transport->recv_stream);
|
||||
stream_free(transport->send_stream);
|
||||
wait_obj_free(transport->recv_event);
|
||||
if (transport->tls)
|
||||
tls_free(transport->tls);
|
||||
tcp_free(transport->tcp);
|
||||
xfree(transport);
|
||||
}
|
||||
|
|
|
@ -216,6 +216,29 @@ void update_reset_state(rdpUpdate* update)
|
|||
update->order_info.orderType = ORDER_TYPE_PATBLT;
|
||||
}
|
||||
|
||||
static void update_begin_paint(rdpUpdate* update)
|
||||
{
|
||||
update_reset_state(update);
|
||||
}
|
||||
|
||||
static void update_end_paint(rdpUpdate* update)
|
||||
{
|
||||
}
|
||||
|
||||
static void update_send_surface_bits(rdpUpdate* update, SURFACE_BITS_COMMAND* surface_bits_command)
|
||||
{
|
||||
rdpRdp* rdp = (rdpRdp*)update->rdp;
|
||||
|
||||
fastpath_send_surface_bits(rdp->fastpath, surface_bits_command);
|
||||
}
|
||||
|
||||
void update_register_server_callbacks(rdpUpdate* update)
|
||||
{
|
||||
update->BeginPaint = update_begin_paint;
|
||||
update->EndPaint = update_end_paint;
|
||||
update->SurfaceBits = update_send_surface_bits;
|
||||
}
|
||||
|
||||
rdpUpdate* update_new(rdpRdp* rdp)
|
||||
{
|
||||
rdpUpdate* update;
|
||||
|
|
|
@ -43,4 +43,6 @@ void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_upda
|
|||
void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update);
|
||||
void update_recv(rdpUpdate* update, STREAM* s);
|
||||
|
||||
void update_register_server_callbacks(rdpUpdate* update);
|
||||
|
||||
#endif /* __UPDATE_H */
|
||||
|
|
|
@ -22,10 +22,154 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/thread.h>
|
||||
#include <freerdp/rfx/rfx.h>
|
||||
#include <freerdp/listener.h>
|
||||
|
||||
/* HL1, LH1, HH1, HL2, LH2, HH2, HL3, LH3, HH3, LL3 */
|
||||
static const unsigned int test_quantization_values[] =
|
||||
{
|
||||
6, 6, 6, 6, 7, 7, 8, 8, 8, 9
|
||||
};
|
||||
|
||||
static const uint8 rgb_scanline_data[] =
|
||||
{
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF,
|
||||
0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF
|
||||
};
|
||||
|
||||
void test_peer_init_desktop(freerdp_peer* client)
|
||||
{
|
||||
rdpUpdate* update = client->update;
|
||||
SURFACE_BITS_COMMAND* cmd = &update->surface_bits_command;
|
||||
RFX_CONTEXT* context;
|
||||
uint8* rgb_data;
|
||||
STREAM* s;
|
||||
int i;
|
||||
RFX_RECT rect = {0, 0, 100, 80};
|
||||
|
||||
rgb_data = (uint8*) xmalloc(100 * 80 * 3);
|
||||
for (i = 0; i < 80; i++)
|
||||
memcpy(rgb_data + i * 100 * 3, rgb_scanline_data, 100 * 3);
|
||||
|
||||
s = stream_new(65536);
|
||||
stream_clear(s);
|
||||
|
||||
context = rfx_context_new();
|
||||
context->mode = RLGR3;
|
||||
context->width = 800;
|
||||
context->height = 600;
|
||||
rfx_context_set_pixel_format(context, RFX_PIXEL_FORMAT_RGB);
|
||||
|
||||
/* In Video mode, the RemoteFX header should only be sent once */
|
||||
rfx_compose_message_header(context, s);
|
||||
|
||||
rfx_compose_message_data(context, s,
|
||||
&rect, 1, rgb_data, 100, 80, 100 * 3);
|
||||
cmd->destLeft = 0;
|
||||
cmd->destTop = 0;
|
||||
cmd->destRight = 100;
|
||||
cmd->destBottom = 80;
|
||||
cmd->bpp = 32;
|
||||
cmd->codecID = CODEC_ID_REMOTEFX;
|
||||
cmd->width = 100;
|
||||
cmd->height = 80;
|
||||
cmd->bitmapDataLength = stream_get_length(s);
|
||||
cmd->bitmapData = stream_get_head(s);
|
||||
update->SurfaceBits(update, cmd);
|
||||
|
||||
stream_free(s);
|
||||
rfx_context_free(context);
|
||||
xfree(rgb_data);
|
||||
}
|
||||
|
||||
boolean test_peer_post_connect(freerdp_peer* client)
|
||||
{
|
||||
/**
|
||||
* This callback is called when the entire connection sequence is done, i.e. we've received the
|
||||
* Font List PDU from the client and sent out the Font Map PDU.
|
||||
* The server may start sending graphics output and receiving keyboard/mouse input after this
|
||||
* callback returns.
|
||||
*/
|
||||
printf("Client %s is activated", client->settings->hostname);
|
||||
if (client->settings->autologon)
|
||||
{
|
||||
printf(" and wants to login automatically as %s\\%s",
|
||||
client->settings->domain ? client->settings->domain : "",
|
||||
client->settings->username);
|
||||
|
||||
/* A real server may perform OS login here if NLA is not executed previously. */
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Client requested desktop: %dx%dx%d\n",
|
||||
client->settings->width, client->settings->height, client->settings->color_depth);
|
||||
|
||||
/* A real server should tag the peer as activated here and start sending updates in mainloop. */
|
||||
test_peer_init_desktop(client);
|
||||
|
||||
/* Return False here would stop the execution of the peer mainloop. */
|
||||
return True;
|
||||
}
|
||||
|
||||
void test_peer_synchronize_event(rdpInput* input, uint32 flags)
|
||||
{
|
||||
printf("Client sent a synchronize event (flags:0x%X)\n", flags);
|
||||
}
|
||||
|
||||
void test_peer_keyboard_event(rdpInput* input, uint16 flags, uint16 code)
|
||||
{
|
||||
printf("Client sent a keyboard event (flags:0x%X code:0x%X)\n", flags, code);
|
||||
}
|
||||
|
||||
void test_peer_unicode_keyboard_event(rdpInput* input, uint16 code)
|
||||
{
|
||||
printf("Client sent a unicode keyboard event (code:0x%X)\n", code);
|
||||
}
|
||||
|
||||
void test_peer_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent a mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
void test_peer_extended_mouse_event(rdpInput* input, uint16 flags, uint16 x, uint16 y)
|
||||
{
|
||||
printf("Client sent an extended mouse event (flags:0x%X pos:%d,%d)\n", flags, x, y);
|
||||
}
|
||||
|
||||
static void* test_peer_mainloop(void* arg)
|
||||
{
|
||||
freerdp_peer* client = (freerdp_peer*)arg;
|
||||
|
@ -40,9 +184,20 @@ static void* test_peer_mainloop(void* arg)
|
|||
|
||||
printf("We've got a client %s\n", client->settings->hostname);
|
||||
|
||||
/* Initialize the real server settings here */
|
||||
client->settings->cert_file = xstrdup("server.crt");
|
||||
client->settings->privatekey_file = xstrdup("server.key");
|
||||
client->settings->nla_security = False;
|
||||
|
||||
client->PostConnect = test_peer_post_connect;
|
||||
|
||||
client->input->param1 = client;
|
||||
client->input->SynchronizeEvent = test_peer_synchronize_event;
|
||||
client->input->KeyboardEvent = test_peer_keyboard_event;
|
||||
client->input->UnicodeKeyboardEvent = test_peer_unicode_keyboard_event;
|
||||
client->input->MouseEvent = test_peer_mouse_event;
|
||||
client->input->ExtendedMouseEvent = test_peer_extended_mouse_event;
|
||||
|
||||
client->Initialize(client);
|
||||
|
||||
while (1)
|
||||
|
|
Loading…
Reference in New Issue