FreeRDP
remdesk_common.c
1 
21 #include "remdesk_common.h"
22 
23 #include <freerdp/channels/log.h>
24 #define TAG CHANNELS_TAG("remdesk.common")
25 
26 UINT remdesk_write_channel_header(wStream* s, const REMDESK_CHANNEL_HEADER* header)
27 {
28  WCHAR ChannelNameW[32] = { 0 };
29 
30  WINPR_ASSERT(s);
31  WINPR_ASSERT(header);
32 
33  for (size_t index = 0; index < 32; index++)
34  {
35  ChannelNameW[index] = (WCHAR)header->ChannelName[index];
36  }
37 
38  const size_t ChannelNameLen =
39  (strnlen(header->ChannelName, sizeof(header->ChannelName)) + 1) * 2;
40  WINPR_ASSERT(ChannelNameLen <= ARRAYSIZE(header->ChannelName));
41 
42  Stream_Write_UINT32(s, (UINT32)ChannelNameLen); /* ChannelNameLen (4 bytes) */
43  Stream_Write_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
44  Stream_Write(s, ChannelNameW, ChannelNameLen); /* ChannelName (variable) */
45  return CHANNEL_RC_OK;
46 }
47 
48 UINT remdesk_write_ctl_header(wStream* s, const REMDESK_CTL_HEADER* ctlHeader)
49 {
50  WINPR_ASSERT(ctlHeader);
51  const UINT error = remdesk_write_channel_header(s, &ctlHeader->ch);
52 
53  if (error != 0)
54  {
55  WLog_ERR(TAG, "remdesk_write_channel_header failed with error %" PRIu32 "!", error);
56  return error;
57  }
58 
59  Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
60  return CHANNEL_RC_OK;
61 }
62 
63 UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
64 {
65  UINT32 ChannelNameLen = 0;
66 
67  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
68  return CHANNEL_RC_NO_MEMORY;
69 
70  Stream_Read_UINT32(s, ChannelNameLen); /* ChannelNameLen (4 bytes) */
71  Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
72 
73  if (ChannelNameLen > 64)
74  {
75  WLog_ERR(TAG, "ChannelNameLen > 64!");
76  return ERROR_INVALID_DATA;
77  }
78 
79  if ((ChannelNameLen % 2) != 0)
80  {
81  WLog_ERR(TAG, "(ChannelNameLen %% 2) != 0!");
82  return ERROR_INVALID_DATA;
83  }
84 
85  if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, ChannelNameLen / sizeof(WCHAR),
86  header->ChannelName,
87  ARRAYSIZE(header->ChannelName)) < 0)
88  return ERROR_INVALID_DATA;
89 
90  return CHANNEL_RC_OK;
91 }
92 
93 UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, size_t msgSize)
94 {
95  WINPR_ASSERT(ctlHeader);
96 
97  if (msgSize > UINT32_MAX - 4)
98  return ERROR_INVALID_PARAMETER;
99 
100  ctlHeader->msgType = msgType;
101  (void)sprintf_s(ctlHeader->ch.ChannelName, ARRAYSIZE(ctlHeader->ch.ChannelName),
102  REMDESK_CHANNEL_CTL_NAME);
103  ctlHeader->ch.DataLength = (UINT32)(4UL + msgSize);
104  return CHANNEL_RC_OK;
105 }