1 | /*␊ |
2 | * aml_generator.c␊ |
3 | * Chameleon␊ |
4 | *␊ |
5 | * Created by Mozodojo on 20/07/10.␊ |
6 | * Copyright 2010 mozo. All rights reserved.␊ |
7 | *␊ |
8 | */␊ |
9 | ␊ |
10 | #include "aml_generator.h"␊ |
11 | ␊ |
12 | unsigned char aml_get_length_size(long length)␊ |
13 | {␊ |
14 | ␉if (length > 0x3F)␊ |
15 | ␉␉return 2;␊ |
16 | ␉else if (length > 0x3FFF) ␊ |
17 | ␉␉return 3;␊ |
18 | ␉␉␊ |
19 | ␉return 1;␊ |
20 | }␊ |
21 | ␊ |
22 | void aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)␊ |
23 | {␊ |
24 | ␉if (parent && node)␊ |
25 | ␉{␊ |
26 | ␉␉if (!parent->First)␊ |
27 | ␉␉␉parent->First = node;␊ |
28 | ␉␉␊ |
29 | ␉␉if (parent->Last)␊ |
30 | ␉␉␉parent->Last->Next = node;␊ |
31 | ␉␉␊ |
32 | ␉␉parent->Last = node;␊ |
33 | ␉}␊ |
34 | }␊ |
35 | ␊ |
36 | struct aml_chunk* aml_create_node(struct aml_chunk* parent)␊ |
37 | {␊ |
38 | ␉struct aml_chunk* node = (void*)malloc(sizeof(struct aml_chunk));␊ |
39 | ␉␊ |
40 | ␉aml_add_to_parent(parent, node);␊ |
41 | ␉␊ |
42 | ␉return node;␊ |
43 | }␊ |
44 | ␊ |
45 | int aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)␊ |
46 | {␊ |
47 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
48 | ␉␊ |
49 | ␉if (node) ␊ |
50 | ␉{␊ |
51 | ␉␉node->Type = AML_CHUNK_NONE;␊ |
52 | ␉␉node->Length = size;␊ |
53 | ␉␉node->Buffer = malloc(node->Length);␊ |
54 | ␉␉memcpy(node->Buffer, buffer, size);␊ |
55 | ␉␉␊ |
56 | ␉␉return node->Length;␊ |
57 | ␉}␊ |
58 | ␉␊ |
59 | ␉return -1;␊ |
60 | }␊ |
61 | ␊ |
62 | int aml_add_byte(struct aml_chunk* parent, unsigned char value)␊ |
63 | {␊ |
64 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
65 | ␉␊ |
66 | ␉if (node) ␊ |
67 | ␉{␊ |
68 | ␉␉node->Type = AML_CHUNK_BYTE;␊ |
69 | ␉␉node->Length = 1;␊ |
70 | ␉␉node->Buffer = malloc(node->Length);␊ |
71 | ␉␉␊ |
72 | ␉␉if (value == 0) ␊ |
73 | ␉␉␉node->Buffer[0] = 0x00;␊ |
74 | ␉␉else if (value == 1)␊ |
75 | ␉␉␉node->Buffer[0] = 0x01;␊ |
76 | ␉␉else ␊ |
77 | ␉␉␉node->Buffer[0] = value;␊ |
78 | ␉␉␊ |
79 | ␉␉return node->Length;␊ |
80 | ␉}␊ |
81 | ␉␊ |
82 | ␉return -1;␊ |
83 | }␊ |
84 | ␊ |
85 | int aml_add_word(struct aml_chunk* parent, unsigned int value)␊ |
86 | {␊ |
87 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
88 | ␉␊ |
89 | ␉if (node) ␊ |
90 | ␉{␊ |
91 | ␉␉node->Type = AML_CHUNK_WORD;␊ |
92 | ␉␉node->Length = 2;␊ |
93 | ␉␉node->Buffer = malloc(node->Length);␊ |
94 | ␉␉node->Buffer[0] = value & 0xff;␊ |
95 | ␉␉node->Buffer[1] = value >> 8;␊ |
96 | ␉␉␊ |
97 | ␉␉return node->Length;␊ |
98 | ␉}␊ |
99 | ␉␊ |
100 | ␉return -1;␊ |
101 | }␊ |
102 | ␊ |
103 | int aml_add_dword(struct aml_chunk* parent, unsigned long value)␊ |
104 | {␊ |
105 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
106 | ␉␊ |
107 | ␉if (node) ␊ |
108 | ␉{␊ |
109 | ␉␉node->Type = AML_CHUNK_DWORD;␊ |
110 | ␉␉node->Length = 4;␊ |
111 | ␉␉node->Buffer = malloc(node->Length);␊ |
112 | ␉␉node->Buffer[0] = value & 0xff;␊ |
113 | ␉␉node->Buffer[1] = (value >> 8) & 0xff;␊ |
114 | ␉␉node->Buffer[2] = (value >> 16) & 0xff;␊ |
115 | ␉␉node->Buffer[3] = (value >> 24) & 0xff;␊ |
116 | ␉␉␊ |
117 | ␉␉return node->Length;␊ |
118 | ␉}␊ |
119 | ␉␊ |
120 | ␉return -1;␊ |
121 | }␊ |
122 | ␊ |
123 | int aml_add_qword(struct aml_chunk* parent, unsigned long long value)␊ |
124 | {␊ |
125 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
126 | ␉␊ |
127 | ␉if (node) ␊ |
128 | ␉{␊ |
129 | ␉␉node->Type = AML_CHUNK_QWORD;␊ |
130 | ␉␉node->Length = 8;␊ |
131 | ␉␉node->Buffer = malloc(node->Length);␊ |
132 | ␉␉node->Buffer[0] = value & 0xff;␊ |
133 | ␉␉node->Buffer[1] = (value >> 8) & 0xff;␊ |
134 | ␉␉node->Buffer[2] = (value >> 16) & 0xff;␊ |
135 | ␉␉node->Buffer[3] = (value >> 24) & 0xff;␊ |
136 | ␉␉node->Buffer[4] = (value >> 32) & 0xff;␊ |
137 | ␉␉node->Buffer[5] = (value >> 40) & 0xff;␊ |
138 | ␉␉node->Buffer[6] = (value >> 48) & 0xff;␊ |
139 | ␉␉node->Buffer[7] = (value >> 56) & 0xff;␊ |
140 | ␉␉␊ |
141 | ␉␉return node->Length;␊ |
142 | ␉}␊ |
143 | ␉␊ |
144 | ␉return -1;␊ |
145 | }␊ |
146 | ␊ |
147 | int aml_fill_simple_name(char* buffer, const char* name)␊ |
148 | {␊ |
149 | ␉int i, len = strlen(name), count = 0;␊ |
150 | ␉␊ |
151 | ␉for (i = 0; i < 4; i++) ␊ |
152 | ␉{␊ |
153 | ␉␉if (i < len && aml_isvalidchar(name[i])) ␊ |
154 | ␉␉{␊ |
155 | ␉␉␉buffer[count++] = name[i];␊ |
156 | ␉␉}␊ |
157 | ␉␉else ␊ |
158 | ␉␉{␊ |
159 | ␉␉␉buffer[3-i] = '_';␊ |
160 | ␉␉}␊ |
161 | ␉}␊ |
162 | ␉␊ |
163 | ␉return 4;␊ |
164 | }␊ |
165 | ␊ |
166 | int aml_get_names_count(const char* name)␊ |
167 | {␊ |
168 | ␉int i, len = strlen(name), count = 0;␊ |
169 | ␉␊ |
170 | ␉for (i = 0; i < len; i++)␊ |
171 | ␉{␊ |
172 | ␉␉if (name[i] == '.') ␊ |
173 | ␉␉{␊ |
174 | ␉␉␉count++;␊ |
175 | ␉␉}␊ |
176 | ␉␉else if (!aml_isvalidchar(name[i]))␊ |
177 | ␉␉{␊ |
178 | ␉␉␉len = i;␊ |
179 | ␉␉␉break;␊ |
180 | ␉␉}␊ |
181 | ␉}␊ |
182 | ␉␊ |
183 | ␉if (count == 0 && len > 0) ␊ |
184 | ␉␉count++;␊ |
185 | ␉␊ |
186 | ␉return count;␊ |
187 | }␊ |
188 | ␊ |
189 | int aml_fill_name(struct aml_chunk* node, const char* name)␊ |
190 | {␊ |
191 | ␉int i, len = strlen(name), count = 0;␊ |
192 | ␉␊ |
193 | ␉for (i = 0; i < len; i++)␊ |
194 | ␉{␊ |
195 | ␉␉if (name[i] == '.') ␊ |
196 | ␉␉{␊ |
197 | ␉␉␉count++;␊ |
198 | ␉␉}␊ |
199 | ␉␉else if (!aml_isvalidchar(name[i]))␊ |
200 | ␉␉{␊ |
201 | ␉␉␉len = i;␊ |
202 | ␉␉␉break;␊ |
203 | ␉␉}␊ |
204 | ␉}␊ |
205 | ␉␊ |
206 | ␉if (count == 0 && len > 0) ␊ |
207 | ␉␉count++;␊ |
208 | ␉␊ |
209 | ␉int offset = 0;␊ |
210 | ␉␊ |
211 | ␉if (count == 1) ␊ |
212 | ␉{␊ |
213 | ␉␉node->Length = 4;␊ |
214 | ␉␉node->Buffer = malloc(node->Length);␊ |
215 | ␉␉aml_fill_simple_name(node->Buffer, name);␊ |
216 | ␉␉return node->Length;␊ |
217 | ␉}␊ |
218 | ␉␊ |
219 | ␉if (count == 2) ␊ |
220 | ␉{␊ |
221 | ␉␉node->Length = 2 + 8;␊ |
222 | ␉␉node->Buffer = malloc(node->Length);␊ |
223 | ␉␉node->Buffer[offset++] = '\\'; // Root␊ |
224 | ␉␉node->Buffer[offset++] = 0x2e; // Double name␊ |
225 | ␉}␊ |
226 | ␉else ␊ |
227 | ␉{␊ |
228 | ␉␉node->Length = 3 + count*4;␊ |
229 | ␉␉node->Buffer[offset++] = '\\'; // Root␊ |
230 | ␉␉node->Buffer[offset++] = 0x2f; // Multi name␊ |
231 | ␉␉node->Buffer[offset++] = count; // Names count␊ |
232 | ␉}␊ |
233 | ␊ |
234 | ␉int j = 0;␊ |
235 | ␉␊ |
236 | ␉for (i = 0; i < count; i++) ␊ |
237 | ␉{␊ |
238 | ␉␉while (name[j] != '.') ␊ |
239 | ␉␉{␊ |
240 | ␉␉␉if (j < len)␊ |
241 | ␉␉␉{␊ |
242 | ␉␉␉␉j++;␊ |
243 | ␉␉␉}␊ |
244 | ␉␉␉else ␊ |
245 | ␉␉␉{␊ |
246 | ␉␉␉␉verbose("aml_fill_name: unexpected end of names path!");␊ |
247 | ␉␉␉␉return -1;␊ |
248 | ␉␉␉}␊ |
249 | ␉␉}␊ |
250 | ␊ |
251 | ␉␉offset += aml_fill_simple_name(node->Buffer + offset, name + j);␊ |
252 | ␉}␊ |
253 | ␉␊ |
254 | ␉return offset;␊ |
255 | }␊ |
256 | ␊ |
257 | int aml_add_name(struct aml_chunk* parent, const char* name, int count, ...)␊ |
258 | {␊ |
259 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
260 | ␉␊ |
261 | ␉if (node)␊ |
262 | ␉{␊ |
263 | ␉␉node->Type = AML_CHUNK_NAME;␊ |
264 | ␉␉␉␊ |
265 | ␉␉aml_fill_name(node, name);␊ |
266 | ␉␉␉␊ |
267 | ␉␉return node->Length;␊ |
268 | ␉}␊ |
269 | ␉␊ |
270 | ␉return -1;␊ |
271 | }␊ |
272 | ␊ |
273 | int aml_add_scope(struct aml_chunk* parent, const char* name)␊ |
274 | {␊ |
275 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
276 | ␉␊ |
277 | ␉if (node)␊ |
278 | ␉{␊ |
279 | ␉␉node->Type = AML_CHUNK_SCOPE;␊ |
280 | ␉␉␊ |
281 | ␉␉aml_fill_name(node, name);␊ |
282 | ␉␉␊ |
283 | ␉␉return node->Length;␊ |
284 | ␉}␊ |
285 | ␉␊ |
286 | ␉return -1;␊ |
287 | } |