Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 193