ReactOS  0.4.14-dev-604-gcfdd483
infput.c
Go to the documentation of this file.
1 /*
2  * PROJECT: .inf file parser
3  * LICENSE: GPL - See COPYING in the top level directory
4  * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
5  */
6 
7 /* INCLUDES *****************************************************************/
8 
9 #include "inflib.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 #define EOL L"\r\n"
15 #define SIZE_INC 1024
16 
17 typedef struct _OUTPUTBUFFER
18 {
25 
26 static void
28 {
29  ULONG Length;
30  PWCHAR NewBuf;
31  ULONG NewSize;
32 
33  /* Skip mode? */
34  if (! INF_SUCCESS(OutBuf->Status))
35  {
36  return;
37  }
38 
39  /* Doesn't fit? */
40  Length = (ULONG)strlenW(Text) * sizeof(WCHAR);
41  if (OutBuf->FreeSize < Length + 1 && INF_SUCCESS(OutBuf->Status))
42  {
43  DPRINT("Out of free space. TotalSize %u FreeSize %u Length %u\n",
44  (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize, (UINT)Length);
45  /* Round up to next SIZE_INC */
46  NewSize = OutBuf->TotalSize +
47  (((Length + 1) - OutBuf->FreeSize + (SIZE_INC - 1)) /
48  SIZE_INC) * SIZE_INC;
49  DPRINT("NewSize %u\n", (UINT)NewSize);
50  NewBuf = MALLOC(NewSize);
51  /* Abort if failed */
52  if (NULL == NewBuf)
53  {
54  DPRINT1("MALLOC() failed\n");
55  OutBuf->Status = INF_STATUS_NO_MEMORY;
56  return;
57  }
58 
59  /* Need to copy old contents? */
60  if (NULL != OutBuf->Buffer)
61  {
62  DPRINT("Copying %u bytes from old content\n",
63  (UINT)(OutBuf->TotalSize - OutBuf->FreeSize));
64  MEMCPY(NewBuf, OutBuf->Buffer, OutBuf->TotalSize - OutBuf->FreeSize);
65  OutBuf->Current = NewBuf + (OutBuf->Current - OutBuf->Buffer);
66  FREE(OutBuf->Buffer);
67  }
68  else
69  {
70  OutBuf->Current = NewBuf;
71  }
72  OutBuf->Buffer = NewBuf;
73  OutBuf->FreeSize += NewSize - OutBuf->TotalSize;
74  OutBuf->TotalSize = NewSize;
75  DPRINT("After reallocation TotalSize %u FreeSize %u\n",
76  (UINT)OutBuf->TotalSize, (UINT)OutBuf->FreeSize);
77  }
78 
79  /* We're guaranteed to have enough room now. Copy char by char because of
80  possible "conversion" from Unicode to Ansi */
81  while (Length--)
82  {
83  *OutBuf->Current++ = *Text++;
84  OutBuf->FreeSize--;
85  }
86  *OutBuf->Current = '\0';
87 }
88 
91  PWCHAR *Buffer,
93 {
94  OUTPUTBUFFER OutBuf;
95  PINFCACHESECTION CacheSection;
96  PINFCACHELINE CacheLine;
97  PINFCACHEFIELD CacheField;
98  PWCHAR p;
99  BOOLEAN NeedQuotes;
100 
101  OutBuf.Buffer = NULL;
102  OutBuf.Current = NULL;
103  OutBuf.FreeSize = 0;
104  OutBuf.TotalSize = 0;
105  OutBuf.Status = INF_STATUS_SUCCESS;
106 
107  /* Iterate through list of sections */
108  CacheSection = Cache->FirstSection;
109  while (CacheSection != NULL)
110  {
111  DPRINT("Processing section %S\n", CacheSection->Name);
112  if (CacheSection != Cache->FirstSection)
113  {
114  Output(&OutBuf, EOL);
115  }
116  Output(&OutBuf, L"[");
117  Output(&OutBuf, CacheSection->Name);
118  Output(&OutBuf, L"]");
119  Output(&OutBuf, EOL);
120 
121  /* Iterate through list of lines */
122  CacheLine = CacheSection->FirstLine;
123  while (CacheLine != NULL)
124  {
125  if (NULL != CacheLine->Key)
126  {
127  DPRINT("Line with key %S\n", CacheLine->Key);
128  Output(&OutBuf, CacheLine->Key);
129  Output(&OutBuf, L" = ");
130  }
131  else
132  {
133  DPRINT("Line without key\n");
134  }
135 
136  /* Iterate through list of lines */
137  CacheField = CacheLine->FirstField;
138  while (CacheField != NULL)
139  {
140  if (CacheField != CacheLine->FirstField)
141  {
142  Output(&OutBuf, L",");
143  }
144  p = CacheField->Data;
145  NeedQuotes = FALSE;
146  while (L'\0' != *p && ! NeedQuotes)
147  {
148  NeedQuotes = (BOOLEAN)(L',' == *p || L';' == *p ||
149  L'\\' == *p);
150  p++;
151  }
152  if (NeedQuotes)
153  {
154  Output(&OutBuf, L"\"");
155  Output(&OutBuf, CacheField->Data);
156  Output(&OutBuf, L"\"");
157  }
158  else
159  {
160  Output(&OutBuf, CacheField->Data);
161  }
162 
163  /* Get the next field */
164  CacheField = CacheField->Next;
165  }
166 
167  Output(&OutBuf, EOL);
168  /* Get the next line */
169  CacheLine = CacheLine->Next;
170  }
171 
172  /* Get the next section */
173  CacheSection = CacheSection->Next;
174  }
175 
176  if (INF_SUCCESS(OutBuf.Status))
177  {
178  *Buffer = OutBuf.Buffer;
179  *BufferSize = OutBuf.TotalSize - OutBuf.FreeSize;
180  }
181  else if (NULL != OutBuf.Buffer)
182  {
183  FREE(OutBuf.Buffer);
184  }
185 
186  return INF_STATUS_SUCCESS;
187 }
188 
189 INFSTATUS
191  PCWSTR Section,
193 {
194  PINFCACHESECTION CacheSection;
195  DPRINT("InfpFindOrAddSection section %S\n", Section);
196 
197  *Context = MALLOC(sizeof(INFCONTEXT));
198  if (NULL == *Context)
199  {
200  DPRINT1("MALLOC() failed\n");
201  return INF_STATUS_NO_MEMORY;
202  }
203 
204  (*Context)->Inf = Cache;
205  (*Context)->Line = 0;
206  CacheSection = InfpFindSection(Cache, Section);
207  if (NULL == CacheSection)
208  {
209  DPRINT("Section not found, creating it\n");
210  CacheSection = InfpAddSection(Cache, Section);
211  if (NULL == CacheSection)
212  {
213  DPRINT("Failed to create section\n");
214  FREE(*Context);
215  return INF_STATUS_NO_MEMORY;
216  }
217  }
218 
219  (*Context)->Section = CacheSection->Id;
220  return INF_STATUS_SUCCESS;
221 }
222 
223 INFSTATUS
225 {
226  PINFCACHESECTION Section;
228 
229  if (NULL == Context)
230  {
231  DPRINT1("Invalid parameter\n");
233  }
234 
236  Line = InfpAddLine(Section);
237  if (NULL == Line)
238  {
239  DPRINT("Failed to create line\n");
240  return INF_STATUS_NO_MEMORY;
241  }
242  Context->Line = Line->Id;
243 
244  if (NULL != Key && NULL == InfpAddKeyToLine(Line, Key))
245  {
246  DPRINT("Failed to add key\n");
247  return INF_STATUS_NO_MEMORY;
248  }
249 
250  return INF_STATUS_SUCCESS;
251 }
252 
253 INFSTATUS
255 {
257 
258  if (NULL == Context)
259  {
260  DPRINT1("Invalid parameter\n");
262  }
263 
265  if (NULL == InfpAddFieldToLine(Line, Data))
266  {
267  DPRINT("Failed to add field\n");
268  return INF_STATUS_NO_MEMORY;
269  }
270 
271  return INF_STATUS_SUCCESS;
272 }
273 
274 /* EOF */
#define INF_SUCCESS(x)
Definition: builddep.h:82
PINFCACHESECTION InfpAddSection(PINFCACHE Cache, PCWSTR Name)
Definition: infcore.c:171
const uint16_t * PCWSTR
Definition: typedefs.h:55
CHAR Name[1]
Definition: inffile.c:59
struct _OUTPUTBUFFER OUTPUTBUFFER
#define MALLOC(Size)
Definition: builddep.h:73
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
Definition: fatfs.h:173
struct _INFCACHEFIELD * Next
Definition: inffile.c:29
ULONG FreeSize
Definition: infput.c:22
#define INF_STATUS_NO_MEMORY
Definition: builddep.h:78
uint16_t * PWCHAR
Definition: typedefs.h:54
PWCHAR Current
Definition: infput.c:20
PWCHAR Buffer
Definition: infput.c:19
int INFSTATUS
Definition: infpriv.h:77
PINFCACHELINE InfpAddLine(PINFCACHESECTION Section)
Definition: infcore.c:217
struct _INFCACHESECTION * Next
Definition: inffile.c:51
static PVOID InfpAddFieldToLine(PINFCACHELINE Line, PCHAR Data)
Definition: inffile.c:331
PINFCACHESECTION InfpFindSection(PINFCACHE Cache, PCWSTR Name)
Definition: infcore.c:143
#define EOL
Definition: infput.c:14
struct _OUTPUTBUFFER * POUTPUTBUFFER
PINFCACHEFIELD FirstField
Definition: inffile.c:44
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
INFSTATUS InfpAddField(PINFCONTEXT Context, PCWSTR Data)
Definition: infput.c:254
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
INFSTATUS Status
Definition: infput.c:23
#define BufferSize
Definition: classpnp.h:419
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: ncftp.h:79
static const WCHAR L[]
Definition: oid.c:1250
#define FREE(ptr, size)
Definition: auth_des.c:64
CHAR Data[1]
Definition: inffile.c:32
#define INF_STATUS_INVALID_PARAMETER
Definition: builddep.h:79
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
static void Output(POUTPUTBUFFER OutBuf, PCWSTR Text)
Definition: infput.c:27
INFSTATUS InfpBuildFileBuffer(PINFCACHE Cache, PWCHAR *Buffer, PULONG BufferSize)
Definition: infput.c:90
PINFCACHELINE FirstLine
Definition: inffile.c:54
#define INF_STATUS_SUCCESS
Definition: builddep.h:77
#define SIZE_INC
Definition: infput.c:15
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define DPRINT1
Definition: precomp.h:8
struct _INFCACHELINE * Next
Definition: inffile.c:37
PINFCACHELINE InfpGetLineForContext(PINFCONTEXT Context)
Definition: infcore.c:310
#define BOOLEAN
Definition: pedump.c:73
static PVOID InfpAddKeyToLine(PINFCACHELINE Line, PCHAR Key)
Definition: inffile.c:309
unsigned int ULONG
Definition: retypes.h:1
INFSTATUS InfpFindOrAddSection(PINFCACHE Cache, PCWSTR Section, PINFCONTEXT *Context)
Definition: infput.c:190
GLfloat GLfloat p
Definition: glext.h:8902
INFSTATUS InfpAddLineWithKey(PINFCONTEXT Context, PCWSTR Key)
Definition: infput.c:224
PINFCACHESECTION InfpGetSectionForContext(PINFCONTEXT Context)
Definition: infcore.c:273
PCHAR Key
Definition: inffile.c:42
struct Line Line
char * Text
Definition: combotst.c:136
ULONG TotalSize
Definition: infput.c:21