Coverage Report

Created: 2026-06-15 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/channels/rdpgfx/rdpgfx_common.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Graphics Pipeline Extension
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2015 Thincast Technologies GmbH
7
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <freerdp/config.h>
23
24
#include <winpr/crt.h>
25
#include <winpr/assert.h>
26
#include <winpr/stream.h>
27
28
#include "rdpgfx_common.h"
29
30
/**
31
 * Function description
32
 *
33
 * @return 0 on success, otherwise a Win32 error code
34
 */
35
UINT rdpgfx_read_header(wLog* log, wStream* s, RDPGFX_HEADER* header, size_t* pPacketLength)
36
0
{
37
0
  WINPR_ASSERT(s);
38
0
  WINPR_ASSERT(header);
39
40
0
  if (pPacketLength)
41
0
    *pPacketLength = 0;
42
43
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
44
0
    return ERROR_INVALID_DATA;
45
46
0
  Stream_Read_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
47
0
  Stream_Read_UINT16(s, header->flags);     /* flags (2 bytes) */
48
0
  Stream_Read_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
49
50
0
  if (header->pduLength < 8)
51
0
  {
52
0
    WLog_Print(log, WLOG_ERROR, "header->pduLength %u less than 8!", header->pduLength);
53
0
    return ERROR_INVALID_DATA;
54
0
  }
55
56
0
  const size_t size = (header->pduLength - 8ull);
57
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, size))
58
0
    return ERROR_INVALID_DATA;
59
0
  if (pPacketLength)
60
0
    *pPacketLength = size;
61
62
0
  return CHANNEL_RC_OK;
63
0
}
64
65
/**
66
 * Function description
67
 *
68
 * @return 0 on success, otherwise a Win32 error code
69
 */
70
UINT rdpgfx_write_header(wStream* s, const RDPGFX_HEADER* header)
71
0
{
72
0
  WINPR_ASSERT(s);
73
0
  WINPR_ASSERT(header);
74
75
0
  if (!Stream_EnsureRemainingCapacity(s, 8))
76
0
    return CHANNEL_RC_NO_MEMORY;
77
0
  Stream_Write_UINT16(s, header->cmdId);     /* cmdId (2 bytes) */
78
0
  Stream_Write_UINT16(s, header->flags);     /* flags (2 bytes) */
79
0
  Stream_Write_UINT32(s, header->pduLength); /* pduLength (4 bytes) */
80
0
  return CHANNEL_RC_OK;
81
0
}
82
83
/**
84
 * Function description
85
 *
86
 * @return 0 on success, otherwise a Win32 error code
87
 */
88
UINT rdpgfx_read_point16(wLog* log, wStream* s, RDPGFX_POINT16* pt16)
89
0
{
90
0
  WINPR_ASSERT(s);
91
0
  WINPR_ASSERT(pt16);
92
93
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
94
0
    return ERROR_INVALID_DATA;
95
96
0
  Stream_Read_UINT16(s, pt16->x); /* x (2 bytes) */
97
0
  Stream_Read_UINT16(s, pt16->y); /* y (2 bytes) */
98
0
  return CHANNEL_RC_OK;
99
0
}
100
101
/**
102
 * Function description
103
 *
104
 * @return 0 on success, otherwise a Win32 error code
105
 */
106
UINT rdpgfx_write_point16(wStream* s, const RDPGFX_POINT16* point16)
107
0
{
108
0
  WINPR_ASSERT(s);
109
0
  WINPR_ASSERT(point16);
110
111
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
112
0
    return CHANNEL_RC_NO_MEMORY;
113
114
0
  Stream_Write_UINT16(s, point16->x); /* x (2 bytes) */
115
0
  Stream_Write_UINT16(s, point16->y); /* y (2 bytes) */
116
0
  return CHANNEL_RC_OK;
117
0
}
118
119
/**
120
 * Function description
121
 *
122
 * @return 0 on success, otherwise a Win32 error code
123
 */
124
UINT rdpgfx_read_rect16(wLog* log, wStream* s, RECTANGLE_16* rect16)
125
0
{
126
0
  WINPR_ASSERT(s);
127
0
  WINPR_ASSERT(rect16);
128
129
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 8))
130
0
    return ERROR_INVALID_DATA;
131
132
0
  Stream_Read_UINT16(s, rect16->left);   /* left (2 bytes) */
133
0
  Stream_Read_UINT16(s, rect16->top);    /* top (2 bytes) */
134
0
  Stream_Read_UINT16(s, rect16->right);  /* right (2 bytes) */
135
0
  Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
136
0
  if (rect16->left >= rect16->right)
137
0
    return ERROR_INVALID_DATA;
138
0
  if (rect16->top >= rect16->bottom)
139
0
    return ERROR_INVALID_DATA;
140
0
  return CHANNEL_RC_OK;
141
0
}
142
143
/**
144
 * Function description
145
 *
146
 * @return 0 on success, otherwise a Win32 error code
147
 */
148
UINT rdpgfx_write_rect16(wStream* s, const RECTANGLE_16* rect16)
149
0
{
150
0
  WINPR_ASSERT(s);
151
0
  WINPR_ASSERT(rect16);
152
153
0
  if (!Stream_EnsureRemainingCapacity(s, 8))
154
0
    return CHANNEL_RC_NO_MEMORY;
155
156
0
  Stream_Write_UINT16(s, rect16->left);   /* left (2 bytes) */
157
0
  Stream_Write_UINT16(s, rect16->top);    /* top (2 bytes) */
158
0
  Stream_Write_UINT16(s, rect16->right);  /* right (2 bytes) */
159
0
  Stream_Write_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
160
0
  return CHANNEL_RC_OK;
161
0
}
162
163
/**
164
 * Function description
165
 *
166
 * @return 0 on success, otherwise a Win32 error code
167
 */
168
UINT rdpgfx_read_color32(wLog* log, wStream* s, RDPGFX_COLOR32* color32)
169
0
{
170
0
  WINPR_ASSERT(s);
171
0
  WINPR_ASSERT(color32);
172
173
0
  if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
174
0
    return ERROR_INVALID_DATA;
175
176
0
  Stream_Read_UINT8(s, color32->B);  /* B (1 byte) */
177
0
  Stream_Read_UINT8(s, color32->G);  /* G (1 byte) */
178
0
  Stream_Read_UINT8(s, color32->R);  /* R (1 byte) */
179
0
  Stream_Read_UINT8(s, color32->XA); /* XA (1 byte) */
180
0
  return CHANNEL_RC_OK;
181
0
}
182
183
/**
184
 * Function description
185
 *
186
 * @return 0 on success, otherwise a Win32 error code
187
 */
188
UINT rdpgfx_write_color32(wStream* s, const RDPGFX_COLOR32* color32)
189
0
{
190
0
  WINPR_ASSERT(s);
191
0
  WINPR_ASSERT(color32);
192
193
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
194
0
    return CHANNEL_RC_NO_MEMORY;
195
196
0
  Stream_Write_UINT8(s, color32->B);  /* B (1 byte) */
197
0
  Stream_Write_UINT8(s, color32->G);  /* G (1 byte) */
198
0
  Stream_Write_UINT8(s, color32->R);  /* R (1 byte) */
199
0
  Stream_Write_UINT8(s, color32->XA); /* XA (1 byte) */
200
0
  return CHANNEL_RC_OK;
201
0
}