2 * PROJECT: .inf file parser
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PROGRAMMER: Royce Mitchell III
6 * Ge van Geldorp <gvg@reactos.org>
9 /* INCLUDES *****************************************************************/
17 /* PRIVATE FUNCTIONS ********************************************************/
19 static int InfpHeapRefCount
;
26 InfpHeap
= RtlCreateHeap(HEAP_GROWABLE
, NULL
, 0, 0, NULL
, NULL
);
28 if (0 <= InfpHeapRefCount
)
35 /* PUBLIC FUNCTIONS *********************************************************/
40 InfSetHeap(PVOID Heap
)
45 InfpHeapRefCount
= -1;
51 InfOpenBufferedFile(PHINF InfHandle
,
65 *ErrorLine
= (ULONG
)-1;
67 /* Allocate file buffer */
68 FileBufferSize
= BufferSize
+ 2;
69 FileBuffer
= MALLOC(FileBufferSize
);
70 if (FileBuffer
== NULL
)
72 DPRINT1("MALLOC() failed\n");
73 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
76 MEMCPY(FileBuffer
, Buffer
, BufferSize
);
78 /* Append string terminator */
79 FileBuffer
[BufferSize
] = 0;
80 FileBuffer
[BufferSize
+ 1] = 0;
82 /* Allocate infcache header */
83 Cache
= (PINFCACHE
)MALLOC(sizeof(INFCACHE
));
86 DPRINT("MALLOC() failed\n");
88 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
91 /* Initialize inicache header */
95 Cache
->LanguageId
= LanguageId
;
97 /* Parse the inf buffer */
98 if (!RtlIsTextUnicode(FileBuffer
, FileBufferSize
, NULL
))
100 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
102 // UINT codepage = CP_ACP;
105 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
107 // codepage = CP_UTF8;
108 // offset = sizeof(utf8_bom);
111 new_buff
= MALLOC(FileBufferSize
* sizeof(WCHAR
));
112 if (new_buff
!= NULL
)
115 Status
= RtlMultiByteToUnicodeN(new_buff
,
116 FileBufferSize
* sizeof(WCHAR
),
118 (char *)FileBuffer
+ offset
,
119 FileBufferSize
- offset
);
121 Status
= InfpParseBuffer(Cache
,
123 new_buff
+ len
/ sizeof(WCHAR
),
128 Status
= INF_STATUS_INSUFFICIENT_RESOURCES
;
132 WCHAR
*new_buff
= (WCHAR
*)FileBuffer
;
133 /* UCS-16 files should start with the Unicode BOM; we should skip it */
134 if (*new_buff
== 0xfeff)
137 FileBufferSize
-= sizeof(WCHAR
);
139 Status
= InfpParseBuffer(Cache
,
141 (WCHAR
*)((char*)new_buff
+ FileBufferSize
),
145 if (!INF_SUCCESS(Status
))
151 /* Free file buffer */
154 *InfHandle
= (HINF
)Cache
;
161 InfOpenFile(PHINF InfHandle
,
162 PUNICODE_STRING FileName
,
166 OBJECT_ATTRIBUTES ObjectAttributes
;
167 FILE_STANDARD_INFORMATION FileInfo
;
168 IO_STATUS_BLOCK IoStatusBlock
;
173 ULONG FileBufferLength
;
174 LARGE_INTEGER FileOffset
;
180 *ErrorLine
= (ULONG
)-1;
182 /* Open the inf file */
183 InitializeObjectAttributes(&ObjectAttributes
,
189 Status
= NtOpenFile(&FileHandle
,
190 GENERIC_READ
| SYNCHRONIZE
,
194 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
);
195 if (!INF_SUCCESS(Status
))
197 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
201 DPRINT("NtOpenFile() successful\n");
203 /* Query file size */
204 Status
= NtQueryInformationFile(FileHandle
,
207 sizeof(FILE_STANDARD_INFORMATION
),
208 FileStandardInformation
);
209 if (!INF_SUCCESS(Status
))
211 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status
);
216 FileLength
= FileInfo
.EndOfFile
.u
.LowPart
;
218 DPRINT("File size: %lu\n", FileLength
);
220 /* Allocate file buffer */
221 FileBufferLength
= FileLength
+ 2;
222 FileBuffer
= MALLOC(FileBufferLength
);
223 if (FileBuffer
== NULL
)
225 DPRINT1("MALLOC() failed\n");
227 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
231 FileOffset
.QuadPart
= 0ULL;
232 Status
= NtReadFile(FileHandle
,
242 /* Append string terminator */
243 FileBuffer
[FileLength
] = 0;
244 FileBuffer
[FileLength
+ 1] = 0;
248 if (!INF_SUCCESS(Status
))
250 DPRINT("NtReadFile() failed (Status %lx)\n", Status
);
255 /* Allocate infcache header */
256 Cache
= (PINFCACHE
)MALLOC(sizeof(INFCACHE
));
259 DPRINT("MALLOC() failed\n");
261 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
264 /* Initialize inicache header */
268 Cache
->LanguageId
= LanguageId
;
270 /* Parse the inf buffer */
271 if (!RtlIsTextUnicode(FileBuffer
, FileBufferLength
, NULL
))
273 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
275 // UINT codepage = CP_ACP;
278 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
280 // codepage = CP_UTF8;
281 // offset = sizeof(utf8_bom);
284 new_buff
= MALLOC(FileBufferLength
* sizeof(WCHAR
));
285 if (new_buff
!= NULL
)
288 Status
= RtlMultiByteToUnicodeN(new_buff
,
289 FileBufferLength
* sizeof(WCHAR
),
291 (char *)FileBuffer
+ offset
,
292 FileBufferLength
- offset
);
294 Status
= InfpParseBuffer(Cache
,
296 new_buff
+ len
/ sizeof(WCHAR
),
301 Status
= INF_STATUS_INSUFFICIENT_RESOURCES
;
305 WCHAR
*new_buff
= (WCHAR
*)FileBuffer
;
306 /* UCS-16 files should start with the Unicode BOM; we should skip it */
307 if (*new_buff
== 0xfeff)
310 FileBufferLength
-= sizeof(WCHAR
);
312 Status
= InfpParseBuffer(Cache
,
314 (WCHAR
*)((char*)new_buff
+ FileBufferLength
),
318 if (!INF_SUCCESS(Status
))
324 /* Free file buffer */
327 *InfHandle
= (HINF
)Cache
;
334 InfCloseFile(HINF InfHandle
)
338 Cache
= (PINFCACHE
)InfHandle
;
345 while (Cache
->FirstSection
!= NULL
)
347 Cache
->FirstSection
= InfpFreeSection(Cache
->FirstSection
);
349 Cache
->LastSection
= NULL
;
353 if (0 < InfpHeapRefCount
)
356 if (0 == InfpHeapRefCount
)
358 RtlDestroyHeap(InfpHeap
);