xref: /reactos/sdk/lib/inflib/infhostgen.c (revision 40462c92)
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       FREE(FileBuffer);
193       fclose(File);
194       return -1;
195     }
196 
197   fclose(File);
198 
199   /* Append string terminator */
200   FileBuffer[FileLength] = 0;
201   FileBuffer[FileLength + 1] = 0;
202 
203   /* Allocate infcache header */
204   Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
205   if (Cache == NULL)
206     {
207       DPRINT1("MALLOC() failed\n");
208       FREE(FileBuffer);
209       return -1;
210     }
211 
212   /* Initialize inicache header */
213   ZEROMEMORY(Cache,
214              sizeof(INFCACHE));
215 
216     Cache->LanguageId = LanguageId;
217 
218   /* Parse the inf buffer */
219     if (!RtlIsTextUnicode(FileBuffer, (INT)FileBufferLength, NULL))
220     {
221 //        static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
222         WCHAR *new_buff;
223 //        UINT codepage = CP_ACP;
224         UINT offset = 0;
225 
226 //        if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
227 //        {
228 //            codepage = CP_UTF8;
229 //            offset = sizeof(utf8_bom);
230 //        }
231 
232         new_buff = MALLOC(FileBufferLength * sizeof(WCHAR));
233         if (new_buff != NULL)
234         {
235             ULONG len;
236             Status = RtlMultiByteToUnicodeN(new_buff,
237                                             FileBufferLength * sizeof(WCHAR),
238                                             &len,
239                                             (char *)FileBuffer + offset,
240                                             FileBufferLength - offset);
241 
242             Status = InfpParseBuffer(Cache,
243                                      new_buff,
244                                      new_buff + len / sizeof(WCHAR),
245                                      ErrorLine);
246 
247             FREE(new_buff);
248         }
249         else
250             Status = INF_STATUS_INSUFFICIENT_RESOURCES;
251     }
252     else
253     {
254         WCHAR *new_buff = (WCHAR *)FileBuffer;
255         /* UCS-16 files should start with the Unicode BOM; we should skip it */
256         if (*new_buff == 0xfeff)
257         {
258             new_buff++;
259             FileBufferLength -= sizeof(WCHAR);
260         }
261         Status = InfpParseBuffer(Cache,
262                                  new_buff,
263                                  (WCHAR*)((char*)new_buff + FileBufferLength),
264                                  ErrorLine);
265     }
266 
267   if (!INF_SUCCESS(Status))
268     {
269       FREE(Cache);
270       Cache = NULL;
271     }
272 
273   /* Free file buffer */
274   FREE(FileBuffer);
275 
276   *InfHandle = (HINF)Cache;
277 
278   return INF_SUCCESS(Status) ? 0 : -1;
279 }
280 
281 
282 void
283 InfHostCloseFile(HINF InfHandle)
284 {
285   PINFCACHE Cache;
286 
287   Cache = (PINFCACHE)InfHandle;
288 
289   if (Cache == NULL)
290     {
291       return;
292     }
293 
294   while (Cache->FirstSection != NULL)
295     {
296       Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
297     }
298   Cache->LastSection = NULL;
299 
300   FREE(Cache);
301 }
302 
303 /* EOF */
304