Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/channels/remdesk/common/remdesk_common.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Remote Assistance Virtual Channel - common components
4
 *
5
 * Copyright 2024 Armin Novak <armin.novak@thincast.com>
6
 * Copyright 2024 Thincast Technologies GmbH
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *   http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
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
0
{
28
0
  WCHAR ChannelNameW[32] = { 0 };
29
30
0
  WINPR_ASSERT(s);
31
0
  WINPR_ASSERT(header);
32
33
0
  for (size_t index = 0; index < 32; index++)
34
0
  {
35
0
    ChannelNameW[index] = (WCHAR)header->ChannelName[index];
36
0
  }
37
38
0
  const size_t ChannelNameLen =
39
0
      (strnlen(header->ChannelName, sizeof(header->ChannelName)) + 1) * 2;
40
0
  WINPR_ASSERT(ChannelNameLen <= ARRAYSIZE(header->ChannelName));
41
42
0
  Stream_Write_UINT32(s, (UINT32)ChannelNameLen); /* ChannelNameLen (4 bytes) */
43
0
  Stream_Write_UINT32(s, header->DataLength);     /* DataLen (4 bytes) */
44
0
  Stream_Write(s, ChannelNameW, ChannelNameLen);  /* ChannelName (variable) */
45
0
  return CHANNEL_RC_OK;
46
0
}
47
48
UINT remdesk_write_ctl_header(wStream* s, const REMDESK_CTL_HEADER* ctlHeader)
49
0
{
50
0
  WINPR_ASSERT(ctlHeader);
51
0
  const UINT error = remdesk_write_channel_header(s, &ctlHeader->ch);
52
53
0
  if (error != 0)
54
0
  {
55
0
    WLog_ERR(TAG, "remdesk_write_channel_header failed with error %" PRIu32 "!", error);
56
0
    return error;
57
0
  }
58
59
0
  Stream_Write_UINT32(s, ctlHeader->msgType); /* msgType (4 bytes) */
60
0
  return CHANNEL_RC_OK;
61
0
}
62
63
UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header)
64
0
{
65
0
  UINT32 ChannelNameLen = 0;
66
67
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
68
0
    return CHANNEL_RC_NO_MEMORY;
69
70
0
  Stream_Read_UINT32(s, ChannelNameLen);     /* ChannelNameLen (4 bytes) */
71
0
  Stream_Read_UINT32(s, header->DataLength); /* DataLen (4 bytes) */
72
73
0
  if (ChannelNameLen > 64)
74
0
  {
75
0
    WLog_ERR(TAG, "ChannelNameLen > 64!");
76
0
    return ERROR_INVALID_DATA;
77
0
  }
78
79
0
  if ((ChannelNameLen % 2) != 0)
80
0
  {
81
0
    WLog_ERR(TAG, "(ChannelNameLen %% 2) != 0!");
82
0
    return ERROR_INVALID_DATA;
83
0
  }
84
85
0
  if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, ChannelNameLen / sizeof(WCHAR),
86
0
                                              header->ChannelName,
87
0
                                              ARRAYSIZE(header->ChannelName)) < 0)
88
0
    return ERROR_INVALID_DATA;
89
90
0
  return CHANNEL_RC_OK;
91
0
}
92
93
UINT remdesk_prepare_ctl_header(REMDESK_CTL_HEADER* ctlHeader, UINT32 msgType, size_t msgSize)
94
0
{
95
0
  WINPR_ASSERT(ctlHeader);
96
97
0
  if (msgSize > UINT32_MAX - 4)
98
0
    return ERROR_INVALID_PARAMETER;
99
100
0
  ctlHeader->msgType = msgType;
101
0
  (void)sprintf_s(ctlHeader->ch.ChannelName, ARRAYSIZE(ctlHeader->ch.ChannelName),
102
0
                  REMDESK_CHANNEL_CTL_NAME);
103
0
  ctlHeader->ch.DataLength = (UINT32)(4UL + msgSize);
104
0
  return CHANNEL_RC_OK;
105
0
}