From 47f3b879db40d49767b8caefb89a70941e71f85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 11 Jan 2014 22:54:08 -0500 Subject: [PATCH] libfreerdp-core: implement parsing of less frequent core rdp messages --- include/freerdp/settings.h | 19 +++++ libfreerdp/core/errinfo.c | 1 - libfreerdp/core/rdp.c | 158 ++++++++++++++++++++++++++++++------- 3 files changed, 147 insertions(+), 31 deletions(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 21a218e2f..361cfba08 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -240,6 +240,15 @@ typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS; #define LOGON_FAILED_OTHER 0x00000002 #define LOGON_WARNING 0x00000003 +/* Server Status Info */ +#define STATUS_FINDING_DESTINATION 0x00000401 +#define STATUS_LOADING_DESTINATION 0x00000402 +#define STATUS_BRINGING_SESSION_ONLINE 0x00000403 +#define STATUS_REDIRECTING_TO_DESTINATION 0x00000404 +#define STATUS_VM_LOADING 0x00000501 +#define STATUS_VM_WAKING 0x00000502 +#define STATUS_VM_BOOTING 0x00000503 + /* SYSTEM_TIME */ typedef struct { @@ -389,6 +398,16 @@ struct rdp_monitor }; typedef struct rdp_monitor rdpMonitor; +struct _MONITOR_DEF +{ + INT32 left; + INT32 top; + INT32 right; + INT32 bottom; + UINT32 flags; +}; +typedef struct _MONITOR_DEF MONITOR_DEF; + /* Device Redirection */ #define RDPDR_DTYP_SERIAL 0x00000001 diff --git a/libfreerdp/core/errinfo.c b/libfreerdp/core/errinfo.c index ab8550c7d..44e3d301e 100644 --- a/libfreerdp/core/errinfo.c +++ b/libfreerdp/core/errinfo.c @@ -568,4 +568,3 @@ void rdp_print_errinfo(UINT32 code) fprintf(stderr, "ERRINFO_UNKNOWN 0x%08X: Unknown error.\n", code); } - diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 01423bdb7..c3f81adf6 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -538,6 +538,41 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id) return TRUE; } +BOOL rdp_recv_server_shutdown_denied_pdu(rdpRdp* rdp, wStream* s) +{ + return TRUE; +} + +BOOL rdp_recv_server_set_keyboard_indicators_pdu(rdpRdp* rdp, wStream* s) +{ + UINT16 unitId; + UINT16 ledFlags; + + if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */ + Stream_Read_UINT16(s, ledFlags); /* ledFlags (2 bytes) */ + + return TRUE; +} + +BOOL rdp_recv_server_set_keyboard_ime_status_pdu(rdpRdp* rdp, wStream* s) +{ + UINT16 unitId; + UINT32 imeState; + UINT32 imeConvMode; + + if (Stream_GetRemainingLength(s) < 10) + return FALSE; + + Stream_Read_UINT16(s, unitId); /* unitId (2 bytes) */ + Stream_Read_UINT32(s, imeState); /* imeState (4 bytes) */ + Stream_Read_UINT32(s, imeConvMode); /* imeConvMode (4 bytes) */ + + return TRUE; +} + BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s) { UINT32 errorInfo; @@ -552,6 +587,87 @@ BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s) return TRUE; } +BOOL rdp_recv_server_auto_reconnect_status_pdu(rdpRdp* rdp, wStream* s) +{ + UINT32 arcStatus; + + if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, arcStatus); /* arcStatus (4 bytes) */ + + return TRUE; +} + +BOOL rdp_recv_server_status_info_pdu(rdpRdp* rdp, wStream* s) +{ + UINT32 statusCode; + + if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, statusCode); /* statusCode (4 bytes) */ + + return TRUE; +} + +BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s) +{ + int index; + UINT32 monitorCount; + MONITOR_DEF* monitor; + MONITOR_DEF* monitorDefArray; + + if (Stream_GetRemainingLength(s) < 4) + return FALSE; + + Stream_Read_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ + + if (Stream_GetRemainingLength(s) < (monitorCount * 20)) + return FALSE; + + monitorDefArray = (MONITOR_DEF*) malloc(sizeof(MONITOR_DEF) * monitorCount); + ZeroMemory(monitorDefArray, sizeof(MONITOR_DEF) * monitorCount); + + for (index = 0; index < monitorCount; index++) + { + monitor = &(monitorDefArray[index]); + + Stream_Read_UINT32(s, monitor->left); /* left (4 bytes) */ + Stream_Read_UINT32(s, monitor->top); /* top (4 bytes) */ + Stream_Read_UINT32(s, monitor->right); /* right (4 bytes) */ + Stream_Read_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ + Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */ + } + + free(monitorDefArray); + + return TRUE; +} + +BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, MONITOR_DEF* monitorDefArray) +{ + int index; + MONITOR_DEF* monitor; + + Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20)); + + Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */ + + for (index = 0; index < monitorCount; index++) + { + monitor = &(monitorDefArray[index]); + + Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */ + Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */ + Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */ + Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */ + Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */ + } + + return TRUE; +} + int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) { BYTE type; @@ -618,29 +734,19 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) return -1; break; - case DATA_PDU_TYPE_INPUT: - break; - case DATA_PDU_TYPE_SYNCHRONIZE: if (!rdp_recv_synchronize_pdu(rdp, cs)) return -1; break; - case DATA_PDU_TYPE_REFRESH_RECT: - break; - case DATA_PDU_TYPE_PLAY_SOUND: if (!update_recv_play_sound(rdp->update, cs)) return -1; break; - case DATA_PDU_TYPE_SUPPRESS_OUTPUT: - break; - - case DATA_PDU_TYPE_SHUTDOWN_REQUEST: - break; - case DATA_PDU_TYPE_SHUTDOWN_DENIED: + if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs)) + return -1; break; case DATA_PDU_TYPE_SAVE_SESSION_INFO: @@ -648,27 +754,19 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) return -1; break; - case DATA_PDU_TYPE_FONT_LIST: - break; - case DATA_PDU_TYPE_FONT_MAP: if (!rdp_recv_font_map_pdu(rdp, cs)) return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: - break; - - case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST: - break; - - case DATA_PDU_TYPE_BITMAP_CACHE_ERROR: + if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs)) + return -1; break; case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS: - break; - - case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR: + if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs)) + return -1; break; case DATA_PDU_TYPE_SET_ERROR_INFO: @@ -676,19 +774,19 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s) return -1; break; - case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR: - break; - - case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR: - break; - case DATA_PDU_TYPE_ARC_STATUS: + if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs)) + return -1; break; case DATA_PDU_TYPE_STATUS_INFO: + if (!rdp_recv_server_status_info_pdu(rdp, cs)) + return -1; break; case DATA_PDU_TYPE_MONITOR_LAYOUT: + if (!rdp_recv_monitor_layout_pdu(rdp, cs)) + return -1; break; default: