Sync with trunk (r47116), hopefully without breaking anything.
[reactos.git] / 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 LANGID LanguageId,
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->LanguageId = LanguageId;
63
64 /* Parse the inf buffer */
65 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferSize, NULL))
66 {
67 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
68 WCHAR *new_buff;
69 // UINT codepage = CP_ACP;
70 UINT offset = 0;
71
72 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
73 // {
74 // codepage = CP_UTF8;
75 // offset = sizeof(utf8_bom);
76 // }
77
78 new_buff = MALLOC(FileBufferSize * sizeof(WCHAR));
79 if (new_buff != NULL)
80 {
81 ULONG len;
82 Status = RtlMultiByteToUnicodeN(new_buff,
83 FileBufferSize * sizeof(WCHAR),
84 &len,
85 (char *)FileBuffer + offset,
86 FileBufferSize - offset);
87
88 Status = InfpParseBuffer(Cache,
89 new_buff,
90 new_buff + len / sizeof(WCHAR),
91 ErrorLine);
92 FREE(new_buff);
93 }
94 else
95 Status = INF_STATUS_INSUFFICIENT_RESOURCES;
96 }
97 else
98 {
99 WCHAR *new_buff = (WCHAR *)FileBuffer;
100 /* UCS-16 files should start with the Unicode BOM; we should skip it */
101 if (*new_buff == 0xfeff)
102 {
103 new_buff++;
104 FileBufferSize -= sizeof(WCHAR);
105 }
106 Status = InfpParseBuffer(Cache,
107 new_buff,
108 (WCHAR*)((char*)new_buff + FileBufferSize),
109 ErrorLine);
110 }
111
112 if (!INF_SUCCESS(Status))
113 {
114 FREE(Cache);
115 Cache = NULL;
116 }
117
118 /* Free file buffer */
119 FREE(FileBuffer);
120
121 *InfHandle = (HINF)Cache;
122
123 return INF_SUCCESS(Status) ? 0 : -1;
124 }
125
126
127 int
128 InfHostOpenFile(PHINF InfHandle,
129 const CHAR *FileName,
130 LANGID LanguageId,
131 ULONG *ErrorLine)
132 {
133 FILE *File;
134 CHAR *FileBuffer;
135 ULONG FileLength;
136 ULONG FileBufferLength;
137 PINFCACHE Cache;
138 INFSTATUS Status = INF_STATUS_SUCCESS;
139
140 *InfHandle = NULL;
141 *ErrorLine = (ULONG)-1;
142
143 /* Open the inf file */
144 File = fopen(FileName, "rb");
145 if (NULL == File)
146 {
147 DPRINT1("fopen() failed (errno %d)\n", errno);
148 return -1;
149 }
150
151 DPRINT("fopen() successful\n");
152
153 /* Query file size */
154 if (fseek(File, (size_t)0, SEEK_END))
155 {
156 DPRINT1("fseek() to EOF failed (errno %d)\n", errno);
157 fclose(File);
158 return -1;
159 }
160
161 FileLength = (ULONG)ftell(File);
162 if ((ULONG) -1 == FileLength)
163 {
164 DPRINT1("ftell() failed (errno %d)\n", errno);
165 fclose(File);
166 return -1;
167 }
168 DPRINT("File size: %u\n", (UINT)FileLength);
169
170 /* Rewind */
171 if (fseek(File, (size_t)0, SEEK_SET))
172 {
173 DPRINT1("fseek() to BOF failed (errno %d)\n", errno);
174 fclose(File);
175 return -1;
176 }
177
178 /* Allocate file buffer */
179 FileBufferLength = FileLength + 2;
180 FileBuffer = MALLOC(FileBufferLength);
181 if (FileBuffer == NULL)
182 {
183 DPRINT1("MALLOC() failed\n");
184 fclose(File);
185 return -1;
186 }
187
188 /* Read file */
189 if (FileLength != fread(FileBuffer, (size_t)1, (size_t)FileLength, File))
190 {
191 DPRINT1("fread() failed (errno %d)\n", errno);
192 fclose(File);
193 return -1;
194 }
195
196 fclose(File);
197
198 /* Append string terminator */
199 FileBuffer[FileLength] = 0;
200 FileBuffer[FileLength + 1] = 0;
201
202 /* Allocate infcache header */
203 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
204 if (Cache == NULL)
205 {
206 DPRINT1("MALLOC() failed\n");
207 FREE(FileBuffer);
208 return -1;
209 }
210
211 /* Initialize inicache header */
212 ZEROMEMORY(Cache,
213 sizeof(INFCACHE));
214
215 Cache->LanguageId = LanguageId;
216
217 /* Parse the inf buffer */
218 if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferLength, NULL))
219 {
220 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
221 WCHAR *new_buff;
222 // UINT codepage = CP_ACP;
223 UINT offset = 0;
224
225 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
226 // {
227 // codepage = CP_UTF8;
228 // offset = sizeof(utf8_bom);
229 // }
230
231 new_buff = MALLOC(FileBufferLength * sizeof(WCHAR));
232 if (new_buff != NULL)
233 {
234 ULONG len;
235 Status = RtlMultiByteToUnicodeN(new_buff,
236 FileBufferLength * sizeof(WCHAR),
237 &len,
238 (char *)FileBuffer + offset,
239 FileBufferLength - offset);
240
241 Status = InfpParseBuffer(Cache,
242 new_buff,
243 new_buff + len / sizeof(WCHAR),
244 ErrorLine);
245
246 FREE(new_buff);
247 }
248 else
249 Status = INF_STATUS_INSUFFICIENT_RESOURCES;
250 }
251 else
252 {
253 WCHAR *new_buff = (WCHAR *)FileBuffer;
254 /* UCS-16 files should start with the Unicode BOM; we should skip it */
255 if (*new_buff == 0xfeff)
256 {
257 new_buff++;
258 FileBufferLength -= sizeof(WCHAR);
259 }
260 Status = InfpParseBuffer(Cache,
261 new_buff,
262 (WCHAR*)((char*)new_buff + FileBufferLength),
263 ErrorLine);
264 }
265
266 if (!INF_SUCCESS(Status))
267 {
268 FREE(Cache);
269 Cache = NULL;
270 }
271
272 /* Free file buffer */
273 FREE(FileBuffer);
274
275 *InfHandle = (HINF)Cache;
276
277 return INF_SUCCESS(Status) ? 0 : -1;
278 }
279
280
281 void
282 InfHostCloseFile(HINF InfHandle)
283 {
284 PINFCACHE Cache;
285
286 Cache = (PINFCACHE)InfHandle;
287
288 if (Cache == NULL)
289 {
290 return;
291 }
292
293 while (Cache->FirstSection != NULL)
294 {
295 Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
296 }
297 Cache->LastSection = NULL;
298
299 FREE(Cache);
300 }
301
302 /* EOF */