- Factor out .inf handling code from usetup
[reactos.git] / reactos / lib / inflib / infhostgen.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: .inf file parser
4 * FILE: lib/inflib/infhostgen.c
5 * PURPOSE: General .inf routines for use on the host build system
6 * PROGRAMMER: Royce Mitchell III
7 * Eric Kohl
8 * Ge van Geldorp
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <stdio.h>
14 #include <errno.h>
15 #include "inflib.h"
16 #include "infhost.h"
17
18 #define NDEBUG
19 #include <debug.h>
20
21 /* PUBLIC FUNCTIONS *********************************************************/
22
23 int
24 InfHostOpenBufferedFile(PHINF InfHandle,
25 void *Buffer,
26 unsigned long BufferSize,
27 unsigned long *ErrorLine)
28 {
29 INFSTATUS Status;
30 PINFCACHE Cache;
31 char *FileBuffer;
32
33 *InfHandle = NULL;
34 *ErrorLine = (unsigned long)-1;
35
36 /* Allocate file buffer */
37 FileBuffer = MALLOC(BufferSize + 1);
38 if (FileBuffer == NULL)
39 {
40 DPRINT1("MALLOC() failed\n");
41 return(INF_STATUS_INSUFFICIENT_RESOURCES);
42 }
43
44 MEMCPY(FileBuffer, Buffer, BufferSize);
45
46 /* Append string terminator */
47 FileBuffer[BufferSize] = 0;
48
49 /* Allocate infcache header */
50 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
51 if (Cache == NULL)
52 {
53 DPRINT("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 /* Parse the inf buffer */
63 Status = InfpParseBuffer (Cache,
64 FileBuffer,
65 FileBuffer + BufferSize,
66 ErrorLine);
67 if (!INF_SUCCESS(Status))
68 {
69 FREE(Cache);
70 Cache = NULL;
71 }
72
73 /* Free file buffer */
74 FREE(FileBuffer);
75
76 *InfHandle = (HINF)Cache;
77
78 return INF_SUCCESS(Status) ? 0 : -1;
79 }
80
81
82 int
83 InfHostOpenFile(PHINF InfHandle,
84 char *FileName,
85 unsigned long *ErrorLine)
86 {
87 FILE *File;
88 char *FileBuffer;
89 unsigned long FileLength;
90 PINFCACHE Cache;
91 INFSTATUS Status;
92
93 *InfHandle = NULL;
94 *ErrorLine = (unsigned long)-1;
95
96 /* Open the inf file */
97 File = fopen(FileName, "rb");
98 if (NULL == File)
99 {
100 DPRINT("fopen() failed (errno %d)\n", errno);
101 return -1;
102 }
103
104 DPRINT("fopen() successful\n");
105
106 /* Query file size */
107 if (fseek(File, 0, SEEK_END))
108 {
109 DPRINT("fseek() to EOF failed (errno %d)\n", errno);
110 fclose(File);
111 return -1;
112 }
113
114 FileLength = ftell(File);
115 if ((unsigned long) -1 == FileLength)
116 {
117 DPRINT("ftell() failed (errno %d)\n", errno);
118 fclose(File);
119 return -1;
120 }
121 DPRINT("File size: %lu\n", FileLength);
122
123 /* Rewind */
124 if (fseek(File, 0, SEEK_SET))
125 {
126 DPRINT("fseek() to BOF failed (errno %d)\n", errno);
127 fclose(File);
128 return -1;
129 }
130
131 /* Allocate file buffer */
132 FileBuffer = MALLOC(FileLength + 1);
133 if (FileBuffer == NULL)
134 {
135 DPRINT1("MALLOC() failed\n");
136 fclose(File);
137 return -1;
138 }
139
140 /* Read file */
141 if (FileLength != fread(FileBuffer, 1, FileLength, File))
142 {
143 DPRINT("fread() failed (errno %d)\n", errno);
144 fclose(File);
145 return -1;
146 }
147
148 fclose(File);
149
150 /* Append string terminator */
151 FileBuffer[FileLength] = 0;
152
153 /* Allocate infcache header */
154 Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
155 if (Cache == NULL)
156 {
157 DPRINT("MALLOC() failed\n");
158 FREE(FileBuffer);
159 return -1;
160 }
161
162 /* Initialize inicache header */
163 ZEROMEMORY(Cache,
164 sizeof(INFCACHE));
165
166 /* Parse the inf buffer */
167 Status = InfpParseBuffer (Cache,
168 FileBuffer,
169 FileBuffer + FileLength,
170 ErrorLine);
171 if (!INF_SUCCESS(Status))
172 {
173 FREE(Cache);
174 Cache = NULL;
175 }
176
177 /* Free file buffer */
178 FREE(FileBuffer);
179
180 *InfHandle = (HINF)Cache;
181
182 return INF_SUCCESS(Status) ? 0 : -1;
183 }
184
185
186 void
187 InfHostCloseFile(HINF InfHandle)
188 {
189 PINFCACHE Cache;
190
191 Cache = (PINFCACHE)InfHandle;
192
193 if (Cache == NULL)
194 {
195 return;
196 }
197
198 while (Cache->FirstSection != NULL)
199 {
200 Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
201 }
202 Cache->LastSection = NULL;
203
204 FREE(Cache);
205 }
206
207 /* EOF */