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
->LocaleId
= LocaleId
;
97 if (!RtlIsTextUnicode(FileBuffer
, FileBufferSize
, NULL
))
99 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
101 // UINT codepage = CP_ACP;
104 // if (BufferSize > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
106 // codepage = CP_UTF8;
107 // offset = sizeof(utf8_bom);
110 new_buff
= MALLOC(FileBufferSize
* sizeof(WCHAR
));
111 if (new_buff
!= NULL
)
113 // DWORD len = MultiByteToWideChar( codepage, 0, (char *)FileBuffer + offset,
114 // FileBufferSize - offset, new_buff, FileBufferSize);
117 Status
= RtlMultiByteToUnicodeN(new_buff
,
118 FileBufferSize
* sizeof(WCHAR
),
120 (char *)FileBuffer
+ offset
,
121 FileBufferSize
- offset
);
123 Status
= InfpParseBuffer(Cache
,
130 Status
= INF_STATUS_INSUFFICIENT_RESOURCES
;
134 WCHAR
*new_buff
= (WCHAR
*)FileBuffer
;
135 /* UCS-16 files should start with the Unicode BOM; we should skip it */
136 if (*new_buff
== 0xfeff)
139 FileBufferSize
-= sizeof(WCHAR
);
141 Status
= InfpParseBuffer(Cache
,
143 (WCHAR
*)((char*)new_buff
+ FileBufferSize
),
147 if (!INF_SUCCESS(Status
))
153 /* Free file buffer */
156 *InfHandle
= (HINF
)Cache
;
163 InfOpenFile(PHINF InfHandle
,
164 PUNICODE_STRING FileName
,
168 OBJECT_ATTRIBUTES ObjectAttributes
;
169 FILE_STANDARD_INFORMATION FileInfo
;
170 IO_STATUS_BLOCK IoStatusBlock
;
175 ULONG FileBufferLength
;
176 LARGE_INTEGER FileOffset
;
182 *ErrorLine
= (ULONG
)-1;
184 /* Open the inf file */
185 InitializeObjectAttributes(&ObjectAttributes
,
191 Status
= NtOpenFile(&FileHandle
,
192 GENERIC_READ
| SYNCHRONIZE
,
196 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_NON_DIRECTORY_FILE
);
197 if (!INF_SUCCESS(Status
))
199 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
203 DPRINT("NtOpenFile() successful\n");
205 /* Query file size */
206 Status
= NtQueryInformationFile(FileHandle
,
209 sizeof(FILE_STANDARD_INFORMATION
),
210 FileStandardInformation
);
211 if (!INF_SUCCESS(Status
))
213 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status
);
218 FileLength
= FileInfo
.EndOfFile
.u
.LowPart
;
220 DPRINT("File size: %lu\n", FileLength
);
222 /* Allocate file buffer */
223 FileBufferLength
= FileLength
+ 2;
224 FileBuffer
= MALLOC(FileBufferLength
);
225 if (FileBuffer
== NULL
)
227 DPRINT1("MALLOC() failed\n");
229 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
233 FileOffset
.QuadPart
= 0ULL;
234 Status
= NtReadFile(FileHandle
,
244 /* Append string terminator */
245 FileBuffer
[FileLength
] = 0;
246 FileBuffer
[FileLength
+ 1] = 0;
250 if (!INF_SUCCESS(Status
))
252 DPRINT("NtReadFile() failed (Status %lx)\n", Status
);
257 /* Allocate infcache header */
258 Cache
= (PINFCACHE
)MALLOC(sizeof(INFCACHE
));
261 DPRINT("MALLOC() failed\n");
263 return(INF_STATUS_INSUFFICIENT_RESOURCES
);
266 /* Initialize inicache header */
270 Cache
->LocaleId
= LocaleId
;
272 /* Parse the inf buffer */
273 if (!RtlIsTextUnicode(FileBuffer
, FileBufferLength
, NULL
))
275 // static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
277 // UINT codepage = CP_ACP;
280 // if (FileLength > sizeof(utf8_bom) && !memcmp(FileBuffer, utf8_bom, sizeof(utf8_bom) ))
282 // codepage = CP_UTF8;
283 // offset = sizeof(utf8_bom);
286 new_buff
= MALLOC(FileBufferLength
* sizeof(WCHAR
));
287 if (new_buff
!= NULL
)
289 // DWORD len = MultiByteToWideChar( codepage, 0, (char *)FileBuffer + offset,
290 // FileLength - offset, new_buff, FileLength);
293 Status
= RtlMultiByteToUnicodeN(new_buff
,
294 FileBufferLength
* sizeof(WCHAR
),
296 (char *)FileBuffer
+ offset
,
297 FileBufferLength
- offset
);
299 Status
= InfpParseBuffer(Cache
,
306 Status
= INF_STATUS_INSUFFICIENT_RESOURCES
;
310 WCHAR
*new_buff
= (WCHAR
*)FileBuffer
;
311 /* UCS-16 files should start with the Unicode BOM; we should skip it */
312 if (*new_buff
== 0xfeff)
315 FileBufferLength
-= sizeof(WCHAR
);
317 Status
= InfpParseBuffer(Cache
,
319 (WCHAR
*)((char*)new_buff
+ FileBufferLength
),
323 if (!INF_SUCCESS(Status
))
329 /* Free file buffer */
332 *InfHandle
= (HINF
)Cache
;
339 InfCloseFile(HINF InfHandle
)
343 Cache
= (PINFCACHE
)InfHandle
;
350 while (Cache
->FirstSection
!= NULL
)
352 Cache
->FirstSection
= InfpFreeSection(Cache
->FirstSection
);
354 Cache
->LastSection
= NULL
;
358 if (0 < InfpHeapRefCount
)
361 if (0 == InfpHeapRefCount
)
363 RtlDestroyHeap(InfpHeap
);