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

Archive Download this file

Revision: 199