Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/channels/rdpei/rdpei_common.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Input Virtual Channel Extension
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2014 David Fort <contact@hardening-consulting.com>
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 <freerdp/config.h>
22
23
#include <winpr/crt.h>
24
#include <winpr/cast.h>
25
#include <winpr/stream.h>
26
27
#include "rdpei_common.h"
28
29
#include <freerdp/log.h>
30
31
#define TAG FREERDP_TAG("channels.rdpei.common")
32
33
BOOL rdpei_read_2byte_unsigned(wStream* s, UINT16* value)
34
0
{
35
0
  BYTE byte = 0;
36
37
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
38
0
    return FALSE;
39
40
0
  Stream_Read_UINT8(s, byte);
41
42
0
  if (byte & 0x80)
43
0
  {
44
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
45
0
      return FALSE;
46
47
0
    const INT32 ibyte = ((byte & 0x7F) << 8);
48
0
    *value = WINPR_ASSERTING_INT_CAST(UINT16, ibyte);
49
0
    Stream_Read_UINT8(s, byte);
50
0
    *value |= byte;
51
0
  }
52
0
  else
53
0
  {
54
0
    *value = (byte & 0x7F);
55
0
  }
56
57
0
  return TRUE;
58
0
}
59
60
BOOL rdpei_write_2byte_unsigned(wStream* s, UINT16 value)
61
0
{
62
0
  BYTE byte = 0;
63
64
0
  if (!Stream_EnsureRemainingCapacity(s, 2))
65
0
    return FALSE;
66
67
0
  if (value > 0x7FFF)
68
0
    return FALSE;
69
70
0
  if (value >= 0x7F)
71
0
  {
72
0
    byte = ((value & 0x7F00) >> 8);
73
0
    Stream_Write_UINT8(s, byte | 0x80);
74
0
    byte = (value & 0xFF);
75
0
    Stream_Write_UINT8(s, byte);
76
0
  }
77
0
  else
78
0
  {
79
0
    byte = (value & 0x7F);
80
0
    Stream_Write_UINT8(s, byte);
81
0
  }
82
83
0
  return TRUE;
84
0
}
85
86
BOOL rdpei_read_2byte_signed(wStream* s, INT16* value)
87
0
{
88
0
  BYTE byte = 0;
89
0
  BOOL negative = 0;
90
91
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
92
0
    return FALSE;
93
94
0
  Stream_Read_UINT8(s, byte);
95
96
0
  negative = (byte & 0x40) ? TRUE : FALSE;
97
98
0
  const BYTE val = (byte & 0x3F);
99
100
0
  if (byte & 0x80)
101
0
  {
102
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
103
0
      return FALSE;
104
105
0
    Stream_Read_UINT8(s, byte);
106
0
    *value = (INT16)((val << 8) | byte);
107
0
  }
108
0
  else
109
0
    *value = val;
110
111
0
  if (negative)
112
0
    *value *= -1;
113
114
0
  return TRUE;
115
0
}
116
117
BOOL rdpei_write_2byte_signed(wStream* s, INT16 value)
118
0
{
119
0
  BYTE byte = 0;
120
0
  BOOL negative = FALSE;
121
122
0
  if (!Stream_EnsureRemainingCapacity(s, 2))
123
0
    return FALSE;
124
125
0
  if (value < 0)
126
0
  {
127
0
    negative = TRUE;
128
0
    value *= -1;
129
0
  }
130
131
0
  if (value > 0x3FFF)
132
0
    return FALSE;
133
134
0
  if (value >= 0x3F)
135
0
  {
136
0
    byte = ((value & 0x3F00) >> 8);
137
138
0
    if (negative)
139
0
      byte |= 0x40;
140
141
0
    Stream_Write_UINT8(s, byte | 0x80);
142
0
    byte = (value & 0xFF);
143
0
    Stream_Write_UINT8(s, byte);
144
0
  }
145
0
  else
146
0
  {
147
0
    byte = (value & 0x3F);
148
149
0
    if (negative)
150
0
      byte |= 0x40;
151
152
0
    Stream_Write_UINT8(s, byte);
153
0
  }
154
155
0
  return TRUE;
156
0
}
157
158
BOOL rdpei_read_4byte_unsigned(wStream* s, UINT32* value)
159
0
{
160
0
  BYTE byte = 0;
161
0
  BYTE count = 0;
162
163
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
164
0
    return FALSE;
165
166
0
  Stream_Read_UINT8(s, byte);
167
168
0
  count = (byte & 0xC0) >> 6;
169
170
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, count))
171
0
    return FALSE;
172
173
0
  switch (count)
174
0
  {
175
0
    case 0:
176
0
      *value = (byte & 0x3F);
177
0
      break;
178
179
0
    case 1:
180
0
      *value = ((byte & 0x3F) << 8) & 0xFF00;
181
0
      Stream_Read_UINT8(s, byte);
182
0
      *value |= byte;
183
0
      break;
184
185
0
    case 2:
186
0
      *value = ((byte & 0x3F) << 16) & 0xFF0000;
187
0
      Stream_Read_UINT8(s, byte);
188
0
      *value |= ((byte << 8) & 0xFF00);
189
0
      Stream_Read_UINT8(s, byte);
190
0
      *value |= byte;
191
0
      break;
192
193
0
    case 3:
194
0
      *value = ((UINT32)(byte & 0x3F) << 24) & 0xFF000000;
195
0
      Stream_Read_UINT8(s, byte);
196
0
      *value |= ((UINT32)(byte << 16) & 0xFF0000);
197
0
      Stream_Read_UINT8(s, byte);
198
0
      *value |= ((UINT32)(byte << 8) & 0xFF00);
199
0
      Stream_Read_UINT8(s, byte);
200
0
      *value |= byte;
201
0
      break;
202
203
0
    default:
204
0
      break;
205
0
  }
206
207
0
  return TRUE;
208
0
}
209
210
BOOL rdpei_write_4byte_unsigned(wStream* s, UINT32 value)
211
0
{
212
0
  BYTE byte = 0;
213
214
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
215
0
    return FALSE;
216
217
0
  if (value <= 0x3FUL)
218
0
  {
219
0
    Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, value));
220
0
  }
221
0
  else if (value <= 0x3FFFUL)
222
0
  {
223
0
    byte = (value >> 8) & 0x3F;
224
0
    Stream_Write_UINT8(s, byte | 0x40);
225
0
    byte = (value & 0xFF);
226
0
    Stream_Write_UINT8(s, byte);
227
0
  }
228
0
  else if (value <= 0x3FFFFFUL)
229
0
  {
230
0
    byte = (value >> 16) & 0x3F;
231
0
    Stream_Write_UINT8(s, byte | 0x80);
232
0
    byte = (value >> 8) & 0xFF;
233
0
    Stream_Write_UINT8(s, byte);
234
0
    byte = (value & 0xFF);
235
0
    Stream_Write_UINT8(s, byte);
236
0
  }
237
0
  else if (value <= 0x3FFFFFFFUL)
238
0
  {
239
0
    byte = (value >> 24) & 0x3F;
240
0
    Stream_Write_UINT8(s, byte | 0xC0);
241
0
    byte = (value >> 16) & 0xFF;
242
0
    Stream_Write_UINT8(s, byte);
243
0
    byte = (value >> 8) & 0xFF;
244
0
    Stream_Write_UINT8(s, byte);
245
0
    byte = (value & 0xFF);
246
0
    Stream_Write_UINT8(s, byte);
247
0
  }
248
0
  else
249
0
  {
250
0
    return FALSE;
251
0
  }
252
253
0
  return TRUE;
254
0
}
255
256
BOOL rdpei_read_4byte_signed(wStream* s, INT32* value)
257
0
{
258
0
  BYTE byte = 0;
259
0
  BYTE count = 0;
260
0
  BOOL negative = 0;
261
262
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
263
0
    return FALSE;
264
265
0
  Stream_Read_UINT8(s, byte);
266
267
0
  count = (byte & 0xC0) >> 6;
268
0
  negative = (byte & 0x20) ? TRUE : FALSE;
269
270
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, count))
271
0
    return FALSE;
272
273
0
  switch (count)
274
0
  {
275
0
    case 0:
276
0
      *value = (byte & 0x1F);
277
0
      break;
278
279
0
    case 1:
280
0
      *value = (byte & 0x1F) << 8;
281
0
      Stream_Read_UINT8(s, byte);
282
0
      *value |= byte;
283
0
      break;
284
285
0
    case 2:
286
0
      *value = (byte & 0x1F) << 16;
287
0
      Stream_Read_UINT8(s, byte);
288
0
      *value |= (byte << 8);
289
0
      Stream_Read_UINT8(s, byte);
290
0
      *value |= byte;
291
0
      break;
292
293
0
    case 3:
294
0
      *value = (byte & 0x1F) << 24;
295
0
      Stream_Read_UINT8(s, byte);
296
0
      *value |= (byte << 16);
297
0
      Stream_Read_UINT8(s, byte);
298
0
      *value |= (byte << 8);
299
0
      Stream_Read_UINT8(s, byte);
300
0
      *value |= byte;
301
0
      break;
302
303
0
    default:
304
0
      break;
305
0
  }
306
307
0
  if (negative)
308
0
    *value *= -1;
309
310
0
  return TRUE;
311
0
}
312
313
BOOL rdpei_write_4byte_signed(wStream* s, INT32 value)
314
0
{
315
0
  BYTE byte = 0;
316
0
  BOOL negative = FALSE;
317
318
0
  if (!Stream_EnsureRemainingCapacity(s, 4))
319
0
    return FALSE;
320
321
0
  if (value < 0)
322
0
  {
323
0
    negative = TRUE;
324
0
    value *= -1;
325
0
  }
326
327
0
  if (value <= 0x1FL)
328
0
  {
329
0
    byte = value & 0x1F;
330
331
0
    if (negative)
332
0
      byte |= 0x20;
333
334
0
    Stream_Write_UINT8(s, byte);
335
0
  }
336
0
  else if (value <= 0x1FFFL)
337
0
  {
338
0
    byte = (value >> 8) & 0x1F;
339
340
0
    if (negative)
341
0
      byte |= 0x20;
342
343
0
    Stream_Write_UINT8(s, byte | 0x40);
344
0
    byte = (value & 0xFF);
345
0
    Stream_Write_UINT8(s, byte);
346
0
  }
347
0
  else if (value <= 0x1FFFFFL)
348
0
  {
349
0
    byte = (value >> 16) & 0x1F;
350
351
0
    if (negative)
352
0
      byte |= 0x20;
353
354
0
    Stream_Write_UINT8(s, byte | 0x80);
355
0
    byte = (value >> 8) & 0xFF;
356
0
    Stream_Write_UINT8(s, byte);
357
0
    byte = (value & 0xFF);
358
0
    Stream_Write_UINT8(s, byte);
359
0
  }
360
0
  else if (value <= 0x1FFFFFFFL)
361
0
  {
362
0
    byte = (value >> 24) & 0x1F;
363
364
0
    if (negative)
365
0
      byte |= 0x20;
366
367
0
    Stream_Write_UINT8(s, byte | 0xC0);
368
0
    byte = (value >> 16) & 0xFF;
369
0
    Stream_Write_UINT8(s, byte);
370
0
    byte = (value >> 8) & 0xFF;
371
0
    Stream_Write_UINT8(s, byte);
372
0
    byte = (value & 0xFF);
373
0
    Stream_Write_UINT8(s, byte);
374
0
  }
375
0
  else
376
0
  {
377
0
    return FALSE;
378
0
  }
379
380
0
  return TRUE;
381
0
}
382
383
BOOL rdpei_read_8byte_unsigned(wStream* s, UINT64* value)
384
0
{
385
0
  UINT64 byte = 0;
386
0
  BYTE count = 0;
387
388
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
389
0
    return FALSE;
390
391
0
  Stream_Read_UINT8(s, byte);
392
393
0
  count = (byte & 0xE0) >> 5;
394
395
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, count))
396
0
    return FALSE;
397
398
0
  switch (count)
399
0
  {
400
0
    case 0:
401
0
      *value = (byte & 0x1F);
402
0
      break;
403
404
0
    case 1:
405
0
      *value = (byte & 0x1FU) << 8U;
406
0
      Stream_Read_UINT8(s, byte);
407
0
      *value |= byte;
408
0
      break;
409
410
0
    case 2:
411
0
      *value = (byte & 0x1FU) << 16U;
412
0
      Stream_Read_UINT8(s, byte);
413
0
      *value |= (byte << 8U);
414
0
      Stream_Read_UINT8(s, byte);
415
0
      *value |= byte;
416
0
      break;
417
418
0
    case 3:
419
0
      *value = (byte & 0x1FU) << 24U;
420
0
      Stream_Read_UINT8(s, byte);
421
0
      *value |= (byte << 16U);
422
0
      Stream_Read_UINT8(s, byte);
423
0
      *value |= (byte << 8U);
424
0
      Stream_Read_UINT8(s, byte);
425
0
      *value |= byte;
426
0
      break;
427
428
0
    case 4:
429
0
      *value = ((byte & 0x1FU)) << 32U;
430
0
      Stream_Read_UINT8(s, byte);
431
0
      *value |= (byte << 24U);
432
0
      Stream_Read_UINT8(s, byte);
433
0
      *value |= (byte << 16U);
434
0
      Stream_Read_UINT8(s, byte);
435
0
      *value |= (byte << 8U);
436
0
      Stream_Read_UINT8(s, byte);
437
0
      *value |= byte;
438
0
      break;
439
440
0
    case 5:
441
0
      *value = ((byte & 0x1FU)) << 40U;
442
0
      Stream_Read_UINT8(s, byte);
443
0
      *value |= ((byte) << 32U);
444
0
      Stream_Read_UINT8(s, byte);
445
0
      *value |= (byte << 24U);
446
0
      Stream_Read_UINT8(s, byte);
447
0
      *value |= (byte << 16U);
448
0
      Stream_Read_UINT8(s, byte);
449
0
      *value |= (byte << 8U);
450
0
      Stream_Read_UINT8(s, byte);
451
0
      *value |= byte;
452
0
      break;
453
454
0
    case 6:
455
0
      *value = ((byte & 0x1FU)) << 48U;
456
0
      Stream_Read_UINT8(s, byte);
457
0
      *value |= ((byte) << 40U);
458
0
      Stream_Read_UINT8(s, byte);
459
0
      *value |= ((byte) << 32U);
460
0
      Stream_Read_UINT8(s, byte);
461
0
      *value |= (byte << 24U);
462
0
      Stream_Read_UINT8(s, byte);
463
0
      *value |= (byte << 16U);
464
0
      Stream_Read_UINT8(s, byte);
465
0
      *value |= (byte << 8U);
466
0
      Stream_Read_UINT8(s, byte);
467
0
      *value |= byte;
468
0
      break;
469
470
0
    case 7:
471
0
      *value = ((byte & 0x1FU)) << 56U;
472
0
      Stream_Read_UINT8(s, byte);
473
0
      *value |= ((byte) << 48U);
474
0
      Stream_Read_UINT8(s, byte);
475
0
      *value |= ((byte) << 40U);
476
0
      Stream_Read_UINT8(s, byte);
477
0
      *value |= ((byte) << 32U);
478
0
      Stream_Read_UINT8(s, byte);
479
0
      *value |= (byte << 24U);
480
0
      Stream_Read_UINT8(s, byte);
481
0
      *value |= (byte << 16U);
482
0
      Stream_Read_UINT8(s, byte);
483
0
      *value |= (byte << 8U);
484
0
      Stream_Read_UINT8(s, byte);
485
0
      *value |= byte;
486
0
      break;
487
488
0
    default:
489
0
      break;
490
0
  }
491
492
0
  return TRUE;
493
0
}
494
495
BOOL rdpei_write_8byte_unsigned(wStream* s, UINT64 value)
496
0
{
497
0
  BYTE byte = 0;
498
499
0
  if (!Stream_EnsureRemainingCapacity(s, 8))
500
0
    return FALSE;
501
502
0
  if (value <= 0x1FULL)
503
0
  {
504
0
    byte = value & 0x1F;
505
0
    Stream_Write_UINT8(s, byte);
506
0
  }
507
0
  else if (value <= 0x1FFFULL)
508
0
  {
509
0
    byte = (value >> 8) & 0x1F;
510
0
    byte |= (1 << 5);
511
0
    Stream_Write_UINT8(s, byte);
512
0
    byte = (value & 0xFF);
513
0
    Stream_Write_UINT8(s, byte);
514
0
  }
515
0
  else if (value <= 0x1FFFFFULL)
516
0
  {
517
0
    byte = (value >> 16) & 0x1F;
518
0
    byte |= (2 << 5);
519
0
    Stream_Write_UINT8(s, byte);
520
0
    byte = (value >> 8) & 0xFF;
521
0
    Stream_Write_UINT8(s, byte);
522
0
    byte = (value & 0xFF);
523
0
    Stream_Write_UINT8(s, byte);
524
0
  }
525
0
  else if (value <= 0x1FFFFFFFULL)
526
0
  {
527
0
    byte = (value >> 24) & 0x1F;
528
0
    byte |= (3 << 5);
529
0
    Stream_Write_UINT8(s, byte);
530
0
    byte = (value >> 16) & 0xFF;
531
0
    Stream_Write_UINT8(s, byte);
532
0
    byte = (value >> 8) & 0xFF;
533
0
    Stream_Write_UINT8(s, byte);
534
0
    byte = (value & 0xFF);
535
0
    Stream_Write_UINT8(s, byte);
536
0
  }
537
0
  else if (value <= 0x1FFFFFFFFFULL)
538
0
  {
539
0
    byte = (value >> 32) & 0x1F;
540
0
    byte |= (4 << 5);
541
0
    Stream_Write_UINT8(s, byte);
542
0
    byte = (value >> 24) & 0x1F;
543
0
    Stream_Write_UINT8(s, byte);
544
0
    byte = (value >> 16) & 0xFF;
545
0
    Stream_Write_UINT8(s, byte);
546
0
    byte = (value >> 8) & 0xFF;
547
0
    Stream_Write_UINT8(s, byte);
548
0
    byte = (value & 0xFF);
549
0
    Stream_Write_UINT8(s, byte);
550
0
  }
551
0
  else if (value <= 0x1FFFFFFFFFFFULL)
552
0
  {
553
0
    byte = (value >> 40) & 0x1F;
554
0
    byte |= (5 << 5);
555
0
    Stream_Write_UINT8(s, byte);
556
0
    byte = (value >> 32) & 0x1F;
557
0
    Stream_Write_UINT8(s, byte);
558
0
    byte = (value >> 24) & 0x1F;
559
0
    Stream_Write_UINT8(s, byte);
560
0
    byte = (value >> 16) & 0xFF;
561
0
    Stream_Write_UINT8(s, byte);
562
0
    byte = (value >> 8) & 0xFF;
563
0
    Stream_Write_UINT8(s, byte);
564
0
    byte = (value & 0xFF);
565
0
    Stream_Write_UINT8(s, byte);
566
0
  }
567
0
  else if (value <= 0x1FFFFFFFFFFFFFULL)
568
0
  {
569
0
    byte = (value >> 48) & 0x1F;
570
0
    byte |= (6 << 5);
571
0
    Stream_Write_UINT8(s, byte);
572
0
    byte = (value >> 40) & 0x1F;
573
0
    Stream_Write_UINT8(s, byte);
574
0
    byte = (value >> 32) & 0x1F;
575
0
    Stream_Write_UINT8(s, byte);
576
0
    byte = (value >> 24) & 0x1F;
577
0
    Stream_Write_UINT8(s, byte);
578
0
    byte = (value >> 16) & 0xFF;
579
0
    Stream_Write_UINT8(s, byte);
580
0
    byte = (value >> 8) & 0xFF;
581
0
    Stream_Write_UINT8(s, byte);
582
0
    byte = (value & 0xFF);
583
0
    Stream_Write_UINT8(s, byte);
584
0
  }
585
0
  else if (value <= 0x1FFFFFFFFFFFFFFFULL)
586
0
  {
587
0
    byte = (value >> 56) & 0x1F;
588
0
    byte |= (7 << 5);
589
0
    Stream_Write_UINT8(s, byte);
590
0
    byte = (value >> 48) & 0x1F;
591
0
    Stream_Write_UINT8(s, byte);
592
0
    byte = (value >> 40) & 0x1F;
593
0
    Stream_Write_UINT8(s, byte);
594
0
    byte = (value >> 32) & 0x1F;
595
0
    Stream_Write_UINT8(s, byte);
596
0
    byte = (value >> 24) & 0x1F;
597
0
    Stream_Write_UINT8(s, byte);
598
0
    byte = (value >> 16) & 0xFF;
599
0
    Stream_Write_UINT8(s, byte);
600
0
    byte = (value >> 8) & 0xFF;
601
0
    Stream_Write_UINT8(s, byte);
602
0
    byte = (value & 0xFF);
603
0
    Stream_Write_UINT8(s, byte);
604
0
  }
605
0
  else
606
0
  {
607
0
    return FALSE;
608
0
  }
609
610
0
  return TRUE;
611
0
}
612
613
void touch_event_reset(RDPINPUT_TOUCH_EVENT* event)
614
0
{
615
0
  for (UINT16 i = 0; i < event->frameCount; i++)
616
0
    touch_frame_reset(&event->frames[i]);
617
618
0
  free(event->frames);
619
0
  event->frames = NULL;
620
0
  event->frameCount = 0;
621
0
}
622
623
void touch_frame_reset(RDPINPUT_TOUCH_FRAME* frame)
624
0
{
625
0
  free(frame->contacts);
626
0
  frame->contacts = NULL;
627
0
  frame->contactCount = 0;
628
0
}
629
630
void pen_event_reset(RDPINPUT_PEN_EVENT* event)
631
0
{
632
0
  for (UINT16 i = 0; i < event->frameCount; i++)
633
0
    pen_frame_reset(&event->frames[i]);
634
635
0
  free(event->frames);
636
0
  event->frames = NULL;
637
0
  event->frameCount = 0;
638
0
}
639
640
void pen_frame_reset(RDPINPUT_PEN_FRAME* frame)
641
0
{
642
0
  free(frame->contacts);
643
0
  frame->contacts = NULL;
644
0
  frame->contactCount = 0;
645
0
}