Coverage Report

Created: 2024-05-20 06:11

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