/**
* xrdp : A Remote Desktop Protocol server .
*
* Copyright ( C ) Jay Sorg 2012 - 2014
* Copyright ( C ) Idan Freiberg 2013 - 2014
*
* 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 .
*/
#if defined (HAVE_CONFIG_H)
#include <config_ac.h>
#endif
#include "libxrdp.h"
#include "ms-rdpbcgr.h"
/*****************************************************************************/
struct xrdp_fastpath *
xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
{
struct xrdp_fastpath *self;
self = (struct xrdp_fastpath *)g_malloc(sizeof (struct xrdp_fastpath), 1 );
self->sec_layer = owner;
self->trans = trans;
self->session = owner->rdp_layer->session;
return self;
}
/*****************************************************************************/
void
xrdp_fastpath_delete(struct xrdp_fastpath *self)
{
if (self == 0 )
{
return ;
}
g_free(self);
}
/*****************************************************************************/
/* returns error */
int
xrdp_fastpath_reset(struct xrdp_fastpath *self)
{
return 0 ;
}
/*****************************************************************************/
int
xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
{
int fp_hdr;
int len = 0 ;
int byte;
char *holdp;
holdp = s->p;
if (!s_check_rem_and_log(s, 2 , "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU" ))
{
return 1 ;
}
in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */
in_uint8(s, byte); /* length 1 (1 byte) */
self->numEvents = (fp_hdr & 0 x3C) >> 2 ;
self->secFlags = (fp_hdr & 0 xC0) >> 6 ;
if (byte & 0 x80)
{
byte &= ~(0 x80);
len = (byte << 8 );
if (!s_check_rem_and_log(s, 1 , "Parsing [MS-RDPBCGR] TS_FP_INPUT_PDU length2" ))
{
return 1 ;
}
in_uint8(s, byte); /* length 2 (1 byte) */
len += byte;
}
else
{
len = byte;
}
s->next_packet = holdp + len;
LOG_DEVEL(LOG_LEVEL_TRACE, "Received header [MS-RDPBCGR] TS_FP_INPUT_PDU "
"fpInputHeader.action (ignored), fpInputHeader.numEvents %d, "
"fpInputHeader.flags 0x%1.1x, length %d" ,
self->numEvents, self->secFlags, len);
return 0 ;
}
/*****************************************************************************/
/* no fragmentation */
int
xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s)
{
int bytes;
bytes = self->session->client_info->max_fastpath_frag_bytes;
if (bytes < 32 * 1024 )
{
bytes = 32 * 1024 ;
}
init_stream(s, bytes);
return 0 ;
}
/*****************************************************************************/
static int
xrdp_fastpath_session_callback(struct xrdp_fastpath *self, int msg,
long param1, long param2,
long param3, long param4)
{
if (self->session->callback != 0 )
{
/* msg_type can be
RDP_INPUT_SYNCHRONIZE - 0
RDP_INPUT_SCANCODE - 4
RDP_INPUT_MOUSE - 0 x8001
RDP_INPUT_MOUSEX - 0x8002 */
/* call to xrdp_wm.c : callback */
self->session->callback(self->session->id, msg,
param1, param2, param3, param4);
}
else
{
LOG_DEVEL(LOG_LEVEL_WARNING, "Bug: session is NULL" );
}
return 0 ;
}
/*****************************************************************************/
/* no fragmentation */
int
xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
{
if (trans_write_copy_s(self->trans, s) != 0 )
{
return 1 ;
}
if (self->session->check_for_app_input)
{
xrdp_fastpath_session_callback(self, 0 x5556, 0 , 0 , 0 , 0 );
}
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SCANCODE */
static int
xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int flags;
int code;
flags = 0 ;
if (!s_check_rem_and_log(s, 1 , "Parsing [MS-RDPBCGR] TS_FP_KEYBOARD_EVENT" ))
{
return 1 ;
}
in_uint8(s, code); /* keyCode (1 byte) */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_KEYBOARD_EVENT "
"eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
"keyCode %d" , eventFlags, code);
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE))
{
flags |= KBD_FLAG_UP;
}
else
{
flags |= KBD_FLAG_DOWN;
}
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
{
flags |= KBD_FLAG_EXT;
}
xrdp_fastpath_session_callback(self, RDP_INPUT_SCANCODE,
code, 0 , flags, 0 );
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_MOUSE */
static int
xrdp_fastpath_process_EVENT_MOUSE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int pointerFlags;
int xPos;
int yPos;
/* eventFlags MUST be zeroed out */
if (eventFlags != 0 )
{
return 1 ;
}
if (!s_check_rem_and_log(s, 2 + 2 + 2 , "Parsing [MS-RDPBCGR] TS_FP_POINTER_EVENT" ))
{
return 1 ;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_POINTER_EVENT "
"eventHeader.eventFlags 0x00, eventHeader.eventCode (ignored), "
"pointerFlags 0x%4.4x, xPos %d, yPos %d" , pointerFlags, xPos, yPos);
xrdp_fastpath_session_callback(self, RDP_INPUT_MOUSE,
xPos, yPos, pointerFlags, 0 );
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_MOUSEX */
static int
xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int pointerFlags;
int xPos;
int yPos;
/* eventFlags MUST be zeroed out */
if (eventFlags != 0 )
{
return 1 ;
}
if (!s_check_rem_and_log(s, 2 + 2 + 2 ,
"Parsing [MS-RDPBCGR] TS_FP_POINTERX_EVENT" ))
{
return 1 ;
}
in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */
in_uint16_le(s, xPos); /* xPos (2 bytes) */
in_uint16_le(s, yPos); /* yPos (2 bytes) */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_POINTERX_EVENT "
"eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
"pointerFlags 0x%4.4x, xPos %d, yPos %d" ,
eventFlags, pointerFlags, xPos, yPos);
xrdp_fastpath_session_callback(self, RDP_INPUT_MOUSEX,
xPos, yPos, pointerFlags, 0 );
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_SYNC */
static int
xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
/*
* The eventCode bitfield ( 3 bits in size ) MUST be set to
* FASTPATH_INPUT_EVENT_SYNC ( 3 ) .
* The eventFlags bitfield ( 5 bits in size ) contains flags
* indicating the " on "
* status of the keyboard toggle keys .
*/
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_SYNC_EVENT"
"eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), " ,
eventFlags);
xrdp_fastpath_session_callback(self, RDP_INPUT_SYNCHRONIZE,
eventFlags, 0 , 0 , 0 );
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT_UNICODE */
static int
xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self,
int eventFlags, struct stream *s)
{
int flags;
int code;
flags = 0 ;
if (!s_check_rem_and_log(s, 2 , "Parsing [MS-RDPBCGR] TS_FP_UNICODE_KEYBOARD_EVENT" ))
{
return 1 ;
}
in_uint16_le(s, code); /* unicode (2 byte) */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_UNICODE_KEYBOARD_EVENT"
"eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode (ignored), "
"unicodeCode %d" ,
eventFlags, code);
if (eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)
{
flags |= KBD_FLAG_UP;
}
else
{
flags |= KBD_FLAG_DOWN;
}
if (eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)
{
flags |= KBD_FLAG_EXT;
}
xrdp_fastpath_session_callback(self, RDP_INPUT_UNICODE,
code, 0 , flags, 0 );
return 0 ;
}
/*****************************************************************************/
/* FASTPATH_INPUT_EVENT */
int
xrdp_fastpath_process_input_event(struct xrdp_fastpath *self,
struct stream *s)
{
int i;
int eventHeader;
int eventCode;
int eventFlags;
/* process fastpath input events */
for (i = 0 ; i < self->numEvents; i++)
{
if (!s_check_rem_and_log(s, 1 , "Parsing [MS-RDPBCGR] TS_FP_INPUT_EVENT eventHeader" ))
{
return 1 ;
}
in_uint8(s, eventHeader);
eventFlags = (eventHeader & 0 x1F);
eventCode = (eventHeader >> 5 );
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_FP_INPUT_EVENT"
"eventHeader.eventFlags 0x%2.2x, eventHeader.eventCode 0x%1.1x" ,
eventFlags, eventCode);
switch (eventCode)
{
case FASTPATH_INPUT_EVENT_SCANCODE:
if (xrdp_fastpath_process_EVENT_SCANCODE(self,
eventFlags,
s) != 0 )
{
return 1 ;
}
break ;
case FASTPATH_INPUT_EVENT_MOUSE:
if (xrdp_fastpath_process_EVENT_MOUSE(self,
eventFlags,
s) != 0 )
{
return 1 ;
}
break ;
case FASTPATH_INPUT_EVENT_MOUSEX:
if (xrdp_fastpath_process_EVENT_MOUSEX(self,
eventFlags,
s) != 0 )
{
return 1 ;
}
break ;
case FASTPATH_INPUT_EVENT_SYNC:
if (xrdp_fastpath_process_EVENT_SYNC(self,
eventFlags,
s) != 0 )
{
return 1 ;
}
break ;
case FASTPATH_INPUT_EVENT_UNICODE:
if (xrdp_fastpath_process_EVENT_UNICODE(self,
eventFlags,
s) != 0 )
{
return 1 ;
}
break ;
default :
LOG(LOG_LEVEL_ERROR, "xrdp_fastpath_process_input_event: "
"unknown eventCode %d" , eventCode);
break ;
}
}
return 0 ;
}
Messung V0.5 in Prozent C=93 H=96 G=94
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-07-10)
¤
*© Formatika GbR, Deutschland