Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazi/i386/libsaio/aml_generator.c

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
12bool aml_add_to_parent(struct aml_chunk* parent, struct aml_chunk* node)
13{
14if (parent && node)
15{
16switch (parent->Type)
17{
18case AML_CHUNK_NONE:
19case AML_CHUNK_BYTE:
20case AML_CHUNK_WORD:
21case AML_CHUNK_DWORD:
22case AML_CHUNK_QWORD:
23case AML_CHUNK_ALIAS:
24//Azi: add line breaks to these msgs (Valv)
25verbose("aml_add_to_parent: node doesn't support child nodes!");
26return false;
27case AML_CHUNK_NAME:
28if (parent->First)
29{
30verbose("aml_add_to_parent: name node supports only one child node!");
31return false;
32}
33break;
34
35default:
36break;
37}
38
39if (!parent->First)
40parent->First = node;
41
42if (parent->Last)
43parent->Last->Next = node;
44
45parent->Last = node;
46
47return true;
48}
49
50return false;
51}
52
53struct aml_chunk* aml_create_node(struct aml_chunk* parent)
54{
55struct aml_chunk* node = (struct aml_chunk*)malloc(sizeof(struct aml_chunk));
56
57aml_add_to_parent(parent, node);
58
59return node;
60}
61
62void aml_destroy_node(struct aml_chunk* node)
63{
64// Delete child nodes
65struct aml_chunk* child = node->First;
66
67while (child)
68{
69struct aml_chunk* next = child->Next;
70
71if (child->Buffer)
72free(child->Buffer);
73
74free(child);
75
76child = next;
77}
78
79// Free node
80if (node->Buffer)
81free(node->Buffer);
82
83free(node);
84}
85
86struct aml_chunk* aml_add_buffer(struct aml_chunk* parent, const char* buffer, unsigned int size)
87{
88struct aml_chunk* node = aml_create_node(parent);
89
90if (node)
91{
92node->Type = AML_CHUNK_NONE;
93node->Length = size;
94node->Buffer = malloc(node->Length);
95memcpy(node->Buffer, buffer, node->Length);
96}
97
98return node;
99}
100
101struct aml_chunk* aml_add_byte(struct aml_chunk* parent, unsigned char value)
102{
103struct aml_chunk* node = aml_create_node(parent);
104
105if (node)
106{
107node->Type = AML_CHUNK_BYTE;
108
109node->Length = 1;
110node->Buffer = malloc(node->Length);
111node->Buffer[0] = value;
112}
113
114return node;
115}
116
117struct aml_chunk* aml_add_word(struct aml_chunk* parent, unsigned int value)
118{
119struct aml_chunk* node = aml_create_node(parent);
120
121if (node)
122{
123node->Type = AML_CHUNK_WORD;
124node->Length = 2;
125node->Buffer = malloc(node->Length);
126node->Buffer[0] = value & 0xff;
127node->Buffer[1] = value >> 8;
128}
129
130return node;
131}
132
133struct aml_chunk* aml_add_dword(struct aml_chunk* parent, unsigned long value)
134{
135struct aml_chunk* node = aml_create_node(parent);
136
137if (node)
138{
139node->Type = AML_CHUNK_DWORD;
140node->Length = 4;
141node->Buffer = malloc(node->Length);
142node->Buffer[0] = value & 0xff;
143node->Buffer[1] = (value >> 8) & 0xff;
144node->Buffer[2] = (value >> 16) & 0xff;
145node->Buffer[3] = (value >> 24) & 0xff;
146}
147
148return node;
149}
150
151struct aml_chunk* aml_add_qword(struct aml_chunk* parent, unsigned long long value)
152{
153struct aml_chunk* node = aml_create_node(parent);
154
155if (node)
156{
157node->Type = AML_CHUNK_QWORD;
158node->Length = 8;
159node->Buffer = malloc(node->Length);
160node->Buffer[0] = value & 0xff;
161node->Buffer[1] = (value >> 8) & 0xff;
162node->Buffer[2] = (value >> 16) & 0xff;
163node->Buffer[3] = (value >> 24) & 0xff;
164node->Buffer[4] = (value >> 32) & 0xff;
165node->Buffer[5] = (value >> 40) & 0xff;
166node->Buffer[6] = (value >> 48) & 0xff;
167node->Buffer[7] = (value >> 56) & 0xff;
168}
169
170return node;
171}
172
173unsigned int aml_fill_simple_name(char* buffer, const char* name)
174{
175if (strlen(name) < 4)
176{
177verbose("aml_fill_simple_name: simple name %s has incorrect lengh! Must be 4.", name);
178return 0;
179}
180
181memcpy(buffer, name, 4);
182return 4;
183}
184
185unsigned int aml_fill_name(struct aml_chunk* node, const char* name)
186{
187if (!node)
188return 0;
189
190int len = strlen(name), offset = 0, count = len / 4;
191
192if ((len % 4) > 1 || count == 0)
193{
194verbose("aml_fill_name: pathname %s has incorrect length! Must be 4, 8, 12, 16, etc...", name);
195return 0;
196}
197
198unsigned int root = 0;
199
200if ((len % 4) == 1 && name[0] == '\\')
201root++;
202
203if (count == 1)
204{
205node->Length = 4 + root;
206node->Buffer = malloc(node->Length);
207memcpy(node->Buffer, name, 4 + root);
208return node->Length;
209}
210
211if (count == 2)
212{
213node->Length = 2 + 8;
214node->Buffer = malloc(node->Length);
215node->Buffer[offset++] = 0x5c; // Root Char
216node->Buffer[offset++] = 0x2e; // Double name
217memcpy(node->Buffer+offset, name + root, 8);
218return node->Length;
219}
220
221node->Length = 3 + count*4;
222node->Buffer = malloc(node->Length);
223node->Buffer[offset++] = 0x5c; // Root Char
224node->Buffer[offset++] = 0x2f; // Multi name
225node->Buffer[offset++] = count; // Names count
226memcpy(node->Buffer+offset, name + root, count*4);
227
228return node->Length;
229}
230
231struct aml_chunk* aml_add_scope(struct aml_chunk* parent, const char* name)
232{
233struct aml_chunk* node = aml_create_node(parent);
234
235if (node)
236{
237node->Type = AML_CHUNK_SCOPE;
238
239aml_fill_name(node, name);
240}
241
242return node;
243}
244
245struct aml_chunk* aml_add_name(struct aml_chunk* parent, const char* name)
246{
247struct aml_chunk* node = aml_create_node(parent);
248
249if (node)
250{
251node->Type = AML_CHUNK_NAME;
252
253aml_fill_name(node, name);
254}
255
256return node;
257}
258
259struct aml_chunk* aml_add_package(struct aml_chunk* parent)
260{
261struct aml_chunk* node = aml_create_node(parent);
262
263if (node)
264{
265node->Type = AML_CHUNK_PACKAGE;
266
267node->Length = 1;
268node->Buffer = malloc(node->Length);
269}
270
271return node;
272}
273
274struct aml_chunk* aml_add_alias(struct aml_chunk* parent, const char* name1, const char* name2)
275{
276struct aml_chunk* node = aml_create_node(parent);
277
278if (node)
279{
280node->Type = AML_CHUNK_ALIAS;
281
282node->Length = 8;
283node->Buffer = malloc(node->Length);
284aml_fill_simple_name(node->Buffer, name1);
285aml_fill_simple_name(node->Buffer+4, name2);
286}
287
288return node;
289}
290
291unsigned char aml_get_size_length(unsigned int size)
292{
293if (size + 1 <= 0x3f)
294return 1;
295else if (size + 2 <= 0x3fff)
296return 2;
297else if (size + 3 <= 0x3fffff)
298return 3;
299
300return 4;
301}
302
303unsigned int aml_calculate_size(struct aml_chunk* node)
304{
305if (node)
306{
307node->Size = 0;
308
309// Calculate child nodes size
310struct aml_chunk* child = node->First;
311unsigned char child_count = 0;
312
313while (child)
314{
315child_count++;
316
317node->Size += aml_calculate_size(child);
318
319child = child->Next;
320}
321
322switch (node->Type)
323{
324case AML_CHUNK_NONE:
325node->Size += node->Length;
326break;
327case AML_CHUNK_SCOPE:
328node->Size += 1 + node->Length;
329node->Size += aml_get_size_length(node->Size);
330break;
331case AML_CHUNK_PACKAGE:
332node->Buffer[0] = child_count;
333node->Size += 1 + node->Length;
334node->Size += aml_get_size_length(node->Size);
335break;
336
337case AML_CHUNK_BYTE:
338if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
339{
340node->Size += node->Length;
341}
342else
343{
344node->Size += 1 + node->Length;
345}
346
347break;
348
349case AML_CHUNK_WORD:
350case AML_CHUNK_DWORD:
351case AML_CHUNK_QWORD:
352case AML_CHUNK_ALIAS:
353case AML_CHUNK_NAME:
354node->Size += 1 + node->Length;
355break;
356}
357
358return node->Size;
359}
360
361return 0;
362}
363
364unsigned int aml_write_byte(unsigned char value, char* buffer, unsigned int offset)
365{
366buffer[offset++] = value;
367
368return offset;
369}
370
371unsigned int aml_write_word(unsigned int value, char* buffer, unsigned int offset)
372{
373buffer[offset++] = value & 0xff;
374buffer[offset++] = value >> 8;
375
376return offset;
377}
378
379unsigned int aml_write_dword(unsigned long value, char* buffer, unsigned int offset)
380{
381buffer[offset++] = value & 0xff;
382buffer[offset++] = (value >> 8) & 0xff;
383buffer[offset++] = (value >> 16) & 0xff;
384buffer[offset++] = (value >> 24) & 0xff;
385
386return offset;
387}
388
389unsigned int aml_write_qword(unsigned long long value, char* buffer, unsigned int offset)
390{
391buffer[offset++] = value & 0xff;
392buffer[offset++] = (value >> 8) & 0xff;
393buffer[offset++] = (value >> 16) & 0xff;
394buffer[offset++] = (value >> 24) & 0xff;
395buffer[offset++] = (value >> 32) & 0xff;
396buffer[offset++] = (value >> 40) & 0xff;
397buffer[offset++] = (value >> 48) & 0xff;
398buffer[offset++] = (value >> 56) & 0xff;
399
400return offset;
401}
402
403unsigned int aml_write_buffer(const char* value, unsigned int size, char* buffer, unsigned int offset)
404{
405if (size > 0)
406{
407memcpy(buffer + offset, value, size);
408}
409
410return offset + size;
411}
412
413unsigned int aml_write_size(unsigned int size, char* buffer, unsigned int offset)
414{
415if (size <= 0x3f)
416{
417buffer[offset++] = size;
418}
419else if (size <= 0x3fff)
420{
421buffer[offset++] = 0x40 | (size & 0xf);
422buffer[offset++] = (size >> 4) & 0xff;
423}
424else if (size <= 0x3fffff)
425{
426buffer[offset++] = 0x80 | (size & 0xf);
427buffer[offset++] = (size >> 4) & 0xff;
428buffer[offset++] = (size >> 12) & 0xff;
429}
430 else
431{
432buffer[offset++] = 0xc0 | (size & 0xf);
433buffer[offset++] = (size >> 4) & 0xff;
434buffer[offset++] = (size >> 12) & 0xff;
435buffer[offset++] = (size >> 20) & 0xff;
436}
437
438return offset;
439}
440
441unsigned int aml_write_node(struct aml_chunk* node, char* buffer, unsigned int offset)
442{
443if (node && buffer)
444{
445unsigned int old = offset;
446
447switch (node->Type)
448{
449case AML_CHUNK_NONE:
450offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
451break;
452
453case AML_CHUNK_SCOPE:
454case AML_CHUNK_PACKAGE:
455offset = aml_write_byte(node->Type, buffer, offset);
456offset = aml_write_size(node->Size-1, buffer, offset);
457offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
458break;
459
460case AML_CHUNK_BYTE:
461if (node->Buffer[0] == 0x0 || node->Buffer[0] == 0x1)
462{
463offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
464}
465else
466{
467offset = aml_write_byte(node->Type, buffer, offset);
468offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
469}
470break;
471
472case AML_CHUNK_WORD:
473case AML_CHUNK_DWORD:
474case AML_CHUNK_QWORD:
475case AML_CHUNK_ALIAS:
476case AML_CHUNK_NAME:
477offset = aml_write_byte(node->Type, buffer, offset);
478offset = aml_write_buffer(node->Buffer, node->Length, buffer, offset);
479break;
480
481default:
482break;
483}
484
485struct aml_chunk* child = node->First;
486
487while (child)
488{
489offset = aml_write_node(child, buffer, offset);
490
491child = child->Next;
492}
493
494if (offset - old != node->Size)
495verbose("Node size incorrect: 0x%x\n", node->Type);
496}
497
498return offset;
499}

Archive Download this file

Revision: 847