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_fill_name(struct aml_chunk* node, const char* name)␊ |
167 | {␊ |
168 | ␉if (!node) ␊ |
169 | ␉␉return -1;␊ |
170 | ␉␊ |
171 | ␉int i, len = strlen(name), count = 0;␊ |
172 | ␉␊ |
173 | ␉for (i = 0; i < len; i++)␊ |
174 | ␉{␊ |
175 | ␉␉if (name[i] == '.') ␊ |
176 | ␉␉{␊ |
177 | ␉␉␉count++;␊ |
178 | ␉␉}␊ |
179 | ␉␉else if (!aml_isvalidchar(name[i]))␊ |
180 | ␉␉{␊ |
181 | ␉␉␉len = i;␊ |
182 | ␉␉␉break;␊ |
183 | ␉␉}␊ |
184 | ␉}␊ |
185 | ␉␊ |
186 | ␉if (count == 0 && len > 0) ␊ |
187 | ␉␉count++;␊ |
188 | ␉␊ |
189 | ␉int offset = 0;␊ |
190 | ␉␊ |
191 | ␉if (count == 1) ␊ |
192 | ␉{␊ |
193 | ␉␉node->Length = 4;␊ |
194 | ␉␉node->Buffer = malloc(node->Length);␊ |
195 | ␉␉aml_fill_simple_name(node->Buffer, name);␊ |
196 | ␉␉return node->Length;␊ |
197 | ␉}␊ |
198 | ␉␊ |
199 | ␉if (count == 2) ␊ |
200 | ␉{␊ |
201 | ␉␉node->Length = 2 + 8;␊ |
202 | ␉␉node->Buffer = malloc(node->Length);␊ |
203 | ␉␉node->Buffer[offset++] = '\\'; // Root␊ |
204 | ␉␉node->Buffer[offset++] = 0x2e; // Double name␊ |
205 | ␉}␊ |
206 | ␉else ␊ |
207 | ␉{␊ |
208 | ␉␉node->Length = 3 + count*4;␊ |
209 | ␉␉node->Buffer[offset++] = '\\'; // Root␊ |
210 | ␉␉node->Buffer[offset++] = 0x2f; // Multi name␊ |
211 | ␉␉node->Buffer[offset++] = count; // Names count␊ |
212 | ␉}␊ |
213 | ␉␊ |
214 | ␉int j = 0;␊ |
215 | ␉␊ |
216 | ␉for (i = 0; i < count; i++) ␊ |
217 | ␉{␊ |
218 | ␉␉offset += aml_fill_simple_name(node->Buffer + offset, name + j);␊ |
219 | ␉␉␊ |
220 | ␉␉while (name[j] != '.') ␊ |
221 | ␉␉{␊ |
222 | ␉␉␉if (j < len)␊ |
223 | ␉␉␉{␊ |
224 | ␉␉␉␉j++;␊ |
225 | ␉␉␉}␊ |
226 | ␉␉␉else ␊ |
227 | ␉␉␉{␊ |
228 | ␉␉␉␉verbose("aml_fill_name: unexpected end of names path!");␊ |
229 | ␉␉␉␉return -1;␊ |
230 | ␉␉␉}␊ |
231 | ␉␉}␊ |
232 | ␉}␊ |
233 | ␉␊ |
234 | ␉return offset;␊ |
235 | }␊ |
236 | ␊ |
237 | int aml_add_name(struct aml_chunk* parent, const char* name, int count, ...)␊ |
238 | {␊ |
239 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
240 | ␉␊ |
241 | ␉if (node)␊ |
242 | ␉{␊ |
243 | ␉␉node->Type = AML_CHUNK_NAME;␊ |
244 | ␉␉␊ |
245 | ␉␉aml_fill_name(node, name);␊ |
246 | ␉␉␊ |
247 | ␉␉return node->Length;␊ |
248 | ␉}␊ |
249 | ␉␊ |
250 | ␉return -1;␊ |
251 | }␊ |
252 | ␊ |
253 | int aml_add_scope(struct aml_chunk* parent, const char* name)␊ |
254 | {␊ |
255 | ␉struct aml_chunk* node = aml_create_node(parent);␊ |
256 | ␉␊ |
257 | ␉if (node)␊ |
258 | ␉{␊ |
259 | ␉␉node->Type = AML_CHUNK_SCOPE;␊ |
260 | ␉␉␊ |
261 | ␉␉aml_fill_name(node, name);␊ |
262 | ␉␉␊ |
263 | ␉␉return node->Length;␊ |
264 | ␉}␊ |
265 | ␉␊ |
266 | ␉return -1;␊ |
267 | } |