[NEWINFLIB]
[reactos.git] / reactos / lib / newinflib / infhostgen.c
1 /*
2 * PROJECT: .inf file parser
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PROGRAMMER: Royce Mitchell III
5 * Eric Kohl
6 * Ge van Geldorp <gvg@reactos.org>
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include "inflib.h"
12 #include "infhost.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* PUBLIC FUNCTIONS *********************************************************/
18
19 int
20 InfHostOpenBufferedFile(PHINF InfHandle,
21 void *Buffer,
22 ULONG BufferSize,
23 LCID LocaleId,
24 ULONG *ErrorLine)
25 {
26 INFSTATUS Status;
27 PINFCACHE Cache;
28 WCHAR *FileBuffer;
29 ULONG FileBufferSize;
30
31 *InfHandle = NULL;
32 *ErrorLine = (ULONG)-1;
33
34 /* Allocate file buffer */
35 FileBufferSize = BufferSize + 2;
36 FileBuffer = MALLOC(FileBufferSize);
37 if (FileBuffer == NULL)
38 {
39 DPRINT1("MALLOC() failed\n");
40 return(INF_STATUS_INSUFFICIENT_RESOURCES);
41 }
42
43 MEMCPY(FileBuffer, Buffer, BufferSize);
44
45 /* Append string terminator */
46 FileBuffer[BufferSize] = 0;
47 FileBuffer[BufferSize + 1] = 0;
48
49 /* Allocate infcache header */
50 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
51 if (Cache == NULL)
52 {
53 DPRINT1("MALLOC() failed\n");
54 FREE(FileBuffer);
55 return(INF_STATUS_INSUFFICIENT_RESOURCES);
56 }
57
58 /* Initialize inicache header */
59 ZEROMEMORY(Cache,
60 sizeof(INFCACHE));
61
62 Cache->LocaleId = LocaleId;
63
64 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferSize, NULL))
65 {
66 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
67 WCHAR *new_buff;
68 // UINT codepage = CP_ACP;
69 UINT offset = 0;
70
71 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
72 // {
73 // codepage = CP_UTF8;
74 // offset = sizeof(utf8_bom);
75 // }
76
77 new_buff = MALLOC(FileBufferSize * sizeof(WCHAR));
78 if (new_buff != NULL)
79 {
80 // DWORD len = MultiByteToWideChar( codepage, 0, (char *)FileBuffer + offset,
81 // FileBufferSize - offset, new_buff, FileBufferSize);
82
83 ULONG len;
84 Status = RtlMultiByteToUnicodeN(new_buff,
85 FileBufferSize * sizeof(WCHAR),
86 &len,
87 (char *)FileBuffer + offset,
88 FileBufferSize - offset);
89
90 Status = InfpParseBuffer(Cache,
91 new_buff,
92 new_buff + len / sizeof(WCHAR),
93 ErrorLine);
94 FREE(new_buff);
95 }
96 else
97 Status = INF_STATUS_INSUFFICIENT_RESOURCES;
98 }
99 else
100 {
101 WCHAR *new_buff = (WCHAR *)FileBuffer;
102 /* UCS-16 files should start with the Unicode BOM; we should skip it */
103 if (*new_buff == 0xfeff)
104 {
105 new_buff++;
106 FileBufferSize -= sizeof(WCHAR);
107 }
108 Status = InfpParseBuffer(Cache,
109 new_buff,
110 (WCHAR*)((char*)new_buff + FileBufferSize),
111 ErrorLine);
112 }
113
114 /* Parse the inf buffer */
115 // Status = InfpParseBuffer (Cache,
116 // FileBuffer,
117 // FileBuffer + BufferSize,
118 // ErrorLine);
119 if (!INF_SUCCESS(Status))
120 {
121 FREE(Cache);
122 Cache = NULL;
123 }
124
125 /* Free file buffer */
126 FREE(FileBuffer);
127
128 *InfHandle = (HINF)Cache;
129
130 return INF_SUCCESS(Status) ? 0 : -1;
131 }
132
133
134 int
135 InfHostOpenFile(PHINF InfHandle,
136 const CHAR *FileName,
137 LCID LocaleId,
138 ULONG *ErrorLine)
139 {
140 FILE *File;
141 CHAR *FileBuffer;
142 ULONG FileLength;
143 ULONG FileBufferLength;
144 PINFCACHE Cache;
145 INFSTATUS Status = INF_STATUS_SUCCESS;
146
147 *InfHandle = NULL;
148 *ErrorLine = (ULONG)-1;
149
150 /* Open the inf file */
151 File = fopen(FileName, "rb");
152 if (NULL == File)
153 {
154 DPRINT1("fopen() failed (errno %d)\n", errno);
155 return -1;
156 }
157
158 DPRINT("fopen() successful\n");
159
160 /* Query file size */
161 if (fseek(File, (size_t)0, SEEK_END))
162 {
163 DPRINT1("fseek() to EOF failed (errno %d)\n", errno);
164 fclose(File);
165 return -1;
166 }
167
168 FileLength = (ULONG)ftell(File);
169 if ((ULONG) -1 == FileLength)
170 {
171 DPRINT1("ftell() failed (errno %d)\n", errno);
172 fclose(File);
173 return -1;
174 }
175 DPRINT("File size: %u\n", (UINT)FileLength);
176
177 /* Rewind */
178 if (fseek(File, (size_t)0, SEEK_SET))
179 {
180 DPRINT1("fseek() to BOF failed (errno %d)\n", errno);
181 fclose(File);
182 return -1;
183 }
184
185 /* Allocate file buffer */
186 FileBufferLength = FileLength + 2;
187 FileBuffer = MALLOC(FileBufferLength);
188 if (FileBuffer == NULL)
189 {
190 DPRINT1("MALLOC() failed\n");
191 fclose(File);
192 return -1;
193 }
194
195 /* Read file */
196 if (FileLength != fread(FileBuffer, (size_t)1, (size_t)FileLength, File))
197 {
198 DPRINT1("fread() failed (errno %d)\n", errno);
199 fclose(File);
200 return -1;
201 }
202
203 fclose(File);
204
205 /* Append string terminator */
206 FileBuffer[FileLength] = 0;
207 FileBuffer[FileLength + 1] = 0;
208
209 /* Allocate infcache header */
210 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
211 if (Cache == NULL)
212 {
213 DPRINT1("MALLOC() failed\n");
214 FREE(FileBuffer);
215 return -1;
216 }
217
218 /* Initialize inicache header */
219 ZEROMEMORY(Cache,
220 sizeof(INFCACHE));
221
222 Cache->LocaleId = LocaleId;
223
224 /* Parse the inf buffer */
225 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferLength, NULL))
226 {
227 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
228 WCHAR *new_buff;
229 // UINT codepage = CP_ACP;
230 UINT offset = 0;
231
232 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
233 // {
234 // codepage = CP_UTF8;
235 // offset = sizeof(utf8_bom);
236 // }
237
238 new_buff = MALLOC(FileBufferLength * sizeof(WCHAR));
239 if (new_buff != NULL)
240 {
241 // DWORD len = MultiByteToWideChar( codepage, 0, (char *)FileBuffer + offset,
242 // FileLength - offset, new_buff, FileLength);
243
244 ULONG len;
245 Status = RtlMultiByteToUnicodeN(new_buff,
246 FileBufferLength * sizeof(WCHAR),
247 &len,
248 (char *)FileBuffer + offset,
249 FileBufferLength - offset);
250
251 Status = InfpParseBuffer(Cache,
252 new_buff,
253 new_buff + len / sizeof(WCHAR),
254 ErrorLine);
255
256 FREE(new_buff);
257 }
258 else
259 Status = INF_STATUS_INSUFFICIENT_RESOURCES;
260 }
261 else
262 {
263 WCHAR *new_buff = (WCHAR *)FileBuffer;
264 /* UCS-16 files should start with the Unicode BOM; we should skip it */
265 if (*new_buff == 0xfeff)
266 {
267 new_buff++;
268 FileBufferLength -= sizeof(WCHAR);
269 }
270 Status = InfpParseBuffer(Cache,
271 new_buff,
272 (WCHAR*)((char*)new_buff + FileBufferLength),
273 ErrorLine);
274 }
275
276 // Status = InfpParseBuffer (Cache,
277 // FileBuffer,
278 // FileBuffer + FileLength,
279 // ErrorLine);
280 if (!INF_SUCCESS(Status))
281 {
282 FREE(Cache);
283 Cache = NULL;
284 }
285
286 /* Free file buffer */
287 FREE(FileBuffer);
288
289 *InfHandle = (HINF)Cache;
290
291 return INF_SUCCESS(Status) ? 0 : -1;
292 }
293
294
295 void
296 InfHostCloseFile(HINF InfHandle)
297 {
298 PINFCACHE Cache;
299
300 Cache = (PINFCACHE)InfHandle;
301
302 if (Cache == NULL)
303 {
304 return;
305 }
306
307 while (Cache->FirstSection != NULL)
308 {
309 Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
310 }
311 Cache->LastSection = NULL;
312
313 FREE(Cache);
314 }
315
316 /* EOF */