[MSTSC] Fix image corruption in 24bpp mode CORE-13224
[reactos.git] / reactos / base / applications / mstsc / asn.c
1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 ASN.1 utility functions
4 Copyright 2012 Henrik Andersson <hean01@cendio.se> for Cendio AB
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "precomp.h"
21
22
23 /* Parse an ASN.1 BER header */
24 RD_BOOL
25 ber_parse_header(STREAM s, int tagval, int *length)
26 {
27 int tag, len;
28
29 if (tagval > 0xff)
30 {
31 in_uint16_be(s, tag);
32 }
33 else
34 {
35 in_uint8(s, tag);
36 }
37
38 if (tag != tagval)
39 {
40 error("expected tag %d, got %d\n", tagval, tag);
41 return False;
42 }
43
44 in_uint8(s, len);
45
46 if (len & 0x80)
47 {
48 len &= ~0x80;
49 *length = 0;
50 while (len--)
51 next_be(s, *length);
52 }
53 else
54 *length = len;
55
56 return s_check(s);
57 }
58
59 /* Output an ASN.1 BER header */
60 void
61 ber_out_header(STREAM s, int tagval, int length)
62 {
63 if (tagval > 0xff)
64 {
65 out_uint16_be(s, tagval);
66 }
67 else
68 {
69 out_uint8(s, tagval);
70 }
71
72 if (length >= 0x80)
73 {
74 out_uint8(s, 0x82);
75 out_uint16_be(s, length);
76 }
77 else
78 out_uint8(s, length);
79 }
80
81 /* Output an ASN.1 BER integer */
82 void
83 ber_out_integer(STREAM s, int value)
84 {
85 ber_out_header(s, BER_TAG_INTEGER, 2);
86 out_uint16_be(s, value);
87 }
88
89 RD_BOOL
90 ber_in_header(STREAM s, int *tagval, int *decoded_len)
91 {
92 in_uint8(s, *tagval);
93 in_uint8(s, *decoded_len);
94
95 if (*decoded_len < 0x80)
96 return True;
97 else if (*decoded_len == 0x81)
98 {
99 in_uint8(s, *decoded_len);
100 return True;
101 }
102 else if (*decoded_len == 0x82)
103 {
104 in_uint16_be(s, *decoded_len);
105 return True;
106 }
107
108 return False;
109 }