Create a branch for header work.
[reactos.git] / lib / inflib / infrosgen.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 "infros.h"
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* PRIVATE FUNCTIONS ********************************************************/
18
19 static int InfpHeapRefCount;
20
21 static VOID
22 CheckHeap()
23 {
24 if (NULL == InfpHeap)
25 {
26 InfpHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
27 }
28 if (0 <= InfpHeapRefCount)
29 {
30 InfpHeapRefCount++;
31 }
32 }
33
34
35 /* PUBLIC FUNCTIONS *********************************************************/
36
37 PVOID InfpHeap;
38
39 VOID
40 InfSetHeap(PVOID Heap)
41 {
42 if (NULL == InfpHeap)
43 {
44 InfpHeap = Heap;
45 InfpHeapRefCount = -1;
46 }
47 }
48
49
50 NTSTATUS
51 InfOpenBufferedFile(PHINF InfHandle,
52 PVOID Buffer,
53 ULONG BufferSize,
54 PULONG ErrorLine)
55 {
56 INFSTATUS Status;
57 PINFCACHE Cache;
58 PCHAR FileBuffer;
59
60 CheckHeap();
61
62 *InfHandle = NULL;
63 *ErrorLine = (ULONG)-1;
64
65 /* Allocate file buffer */
66 FileBuffer = MALLOC(BufferSize + 1);
67 if (FileBuffer == NULL)
68 {
69 DPRINT1("MALLOC() failed\n");
70 return(INF_STATUS_INSUFFICIENT_RESOURCES);
71 }
72
73 MEMCPY(FileBuffer, Buffer, BufferSize);
74
75 /* Append string terminator */
76 FileBuffer[BufferSize] = 0;
77
78 /* Allocate infcache header */
79 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
80 if (Cache == NULL)
81 {
82 DPRINT("MALLOC() failed\n");
83 FREE(FileBuffer);
84 return(INF_STATUS_INSUFFICIENT_RESOURCES);
85 }
86
87 /* Initialize inicache header */
88 ZEROMEMORY(Cache,
89 sizeof(INFCACHE));
90
91 /* Parse the inf buffer */
92 Status = InfpParseBuffer (Cache,
93 FileBuffer,
94 FileBuffer + BufferSize,
95 ErrorLine);
96 if (!INF_SUCCESS(Status))
97 {
98 FREE(Cache);
99 Cache = NULL;
100 }
101
102 /* Free file buffer */
103 FREE(FileBuffer);
104
105 *InfHandle = (HINF)Cache;
106
107 return(Status);
108 }
109
110
111 NTSTATUS
112 InfOpenFile(PHINF InfHandle,
113 PUNICODE_STRING FileName,
114 PULONG ErrorLine)
115 {
116 OBJECT_ATTRIBUTES ObjectAttributes;
117 FILE_STANDARD_INFORMATION FileInfo;
118 IO_STATUS_BLOCK IoStatusBlock;
119 HANDLE FileHandle;
120 NTSTATUS Status;
121 PCHAR FileBuffer;
122 ULONG FileLength;
123 LARGE_INTEGER FileOffset;
124 PINFCACHE Cache;
125
126 CheckHeap();
127
128 *InfHandle = NULL;
129 *ErrorLine = (ULONG)-1;
130
131 /* Open the inf file */
132 InitializeObjectAttributes(&ObjectAttributes,
133 FileName,
134 0,
135 NULL,
136 NULL);
137
138 Status = NtOpenFile(&FileHandle,
139 GENERIC_READ | SYNCHRONIZE,
140 &ObjectAttributes,
141 &IoStatusBlock,
142 FILE_SHARE_READ,
143 FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
144 if (!INF_SUCCESS(Status))
145 {
146 DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
147 return(Status);
148 }
149
150 DPRINT("NtOpenFile() successful\n");
151
152 /* Query file size */
153 Status = NtQueryInformationFile(FileHandle,
154 &IoStatusBlock,
155 &FileInfo,
156 sizeof(FILE_STANDARD_INFORMATION),
157 FileStandardInformation);
158 if (!INF_SUCCESS(Status))
159 {
160 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
161 NtClose(FileHandle);
162 return(Status);
163 }
164
165 FileLength = FileInfo.EndOfFile.u.LowPart;
166
167 DPRINT("File size: %lu\n", FileLength);
168
169 /* Allocate file buffer */
170 FileBuffer = MALLOC(FileLength + 1);
171 if (FileBuffer == NULL)
172 {
173 DPRINT1("MALLOC() failed\n");
174 NtClose(FileHandle);
175 return(INF_STATUS_INSUFFICIENT_RESOURCES);
176 }
177
178 /* Read file */
179 FileOffset.QuadPart = 0ULL;
180 Status = NtReadFile(FileHandle,
181 NULL,
182 NULL,
183 NULL,
184 &IoStatusBlock,
185 FileBuffer,
186 FileLength,
187 &FileOffset,
188 NULL);
189
190 /* Append string terminator */
191 FileBuffer[FileLength] = 0;
192
193 NtClose(FileHandle);
194
195 if (!INF_SUCCESS(Status))
196 {
197 DPRINT("NtReadFile() failed (Status %lx)\n", Status);
198 FREE(FileBuffer);
199 return(Status);
200 }
201
202 /* Allocate infcache header */
203 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
204 if (Cache == NULL)
205 {
206 DPRINT("MALLOC() failed\n");
207 FREE(FileBuffer);
208 return(INF_STATUS_INSUFFICIENT_RESOURCES);
209 }
210
211 /* Initialize inicache header */
212 ZEROMEMORY(Cache,
213 sizeof(INFCACHE));
214
215 /* Parse the inf buffer */
216 Status = InfpParseBuffer (Cache,
217 FileBuffer,
218 FileBuffer + FileLength,
219 ErrorLine);
220 if (!INF_SUCCESS(Status))
221 {
222 FREE(Cache);
223 Cache = NULL;
224 }
225
226 /* Free file buffer */
227 FREE(FileBuffer);
228
229 *InfHandle = (HINF)Cache;
230
231 return(Status);
232 }
233
234
235 VOID
236 InfCloseFile(HINF InfHandle)
237 {
238 PINFCACHE Cache;
239
240 Cache = (PINFCACHE)InfHandle;
241
242 if (Cache == NULL)
243 {
244 return;
245 }
246
247 while (Cache->FirstSection != NULL)
248 {
249 Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
250 }
251 Cache->LastSection = NULL;
252
253 FREE(Cache);
254
255 if (0 < InfpHeapRefCount)
256 {
257 InfpHeapRefCount--;
258 if (0 == InfpHeapRefCount)
259 {
260 RtlDestroyHeap(InfpHeap);
261 InfpHeap = NULL;
262 }
263 }
264 }
265
266
267 /* EOF */