ReactOS  0.4.13-dev-66-gc714b7f
infget.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  * PROGRAMMER: Royce Mitchell III
5  * Eric Kohl
6  * Ge van Geldorp <gvg@reactos.org>
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include "inflib.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 static size_t
18  const WCHAR *text,
19  WCHAR *buffer,
20  size_t size);
21 
22 static void
24  USHORT Value)
25 {
26  WCHAR HexDigits[] = L"0123456789abcdef";
27 
28  Buffer[0] = HexDigits[Value >> 12 & 0xf];
29  Buffer[1] = HexDigits[Value >> 8 & 0xf];
30  Buffer[2] = HexDigits[Value >> 4 & 0xf];
31  Buffer[3] = HexDigits[Value >> 0 & 0xf];
32 }
33 
34 /* retrieve the string substitution for a given string, or NULL if not found */
35 /* if found, len is set to the substitution length */
36 static PCWSTR
38  PCWSTR str,
39  size_t *len,
40  BOOL no_trailing_slash)
41 {
42  static const WCHAR percent = '%';
43 
46  PWCHAR Data = NULL;
48  WCHAR StringLangId[] = L"Strings.XXXX";
49 
50  if (!*len) /* empty string (%%) is replaced by single percent */
51  {
52  *len = 1;
53  return &percent;
54  }
55 
56  memcpy(ValueName, str, *len * sizeof(WCHAR));
57  ValueName[*len] = 0;
58 
59  DPRINT("Value name: %S\n", ValueName);
60 
61  if (Inf->LanguageId != 0)
62  {
63  ShortToHex(&StringLangId[sizeof("Strings.") - 1],
64  Inf->LanguageId);
65 
67  StringLangId,
68  ValueName,
69  &Context);
71  {
72  ShortToHex(&StringLangId[sizeof("Strings.") - 1],
74 
76  StringLangId,
77  ValueName,
78  &Context);
80  {
82  L"Strings",
83  ValueName,
84  &Context);
85  }
86  }
87  }
88  else
89  {
91  L"Strings",
92  ValueName,
93  &Context);
94  }
95 
97  return NULL;
98 
100  NULL,
101  &Data);
102 
104 
105  if (Status == STATUS_SUCCESS)
106  {
107  *len = strlenW(Data);
108  DPRINT("Substitute: %S Length: %zu\n", Data, *len);
109  return Data;
110  }
111 
112  return NULL;
113 }
114 
115 
116 /* do string substitutions on the specified text */
117 /* the buffer is assumed to be large enough */
118 /* returns necessary length not including terminating null */
119 static size_t
121  PCWSTR text,
122  PWSTR buffer,
123  size_t size)
124 {
125  const WCHAR *start, *subst, *p;
126  size_t len, total = 0;
127  int inside = 0;
128 
129  if (!buffer) size = MAX_INF_STRING_LENGTH + 1;
130  for (p = start = text; *p; p++)
131  {
132  if (*p != '%') continue;
133  inside = !inside;
134  if (inside) /* start of a %xx% string */
135  {
136  len = (p - start);
137  if (len > size - 1) len = size - 1;
138  if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
139  total += len;
140  size -= len;
141  start = p;
142  }
143  else /* end of the %xx% string, find substitution */
144  {
145  len = (p - start - 1);
146  subst = InfpGetSubstitutionString( Inf, start + 1, &len, p[1] == '\\' );
147  if (!subst)
148  {
149  subst = start;
150  len = (p - start + 1);
151  }
152  if (len > size - 1) len = size - 1;
153  if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );
154  total += len;
155  size -= len;
156  start = p + 1;
157  }
158  }
159 
160  if (start != p) /* unfinished string, copy it */
161  {
162  len = (unsigned int)(p - start);
163  if (len > size - 1) len = size - 1;
164  if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
165  total += len;
166  }
167  if (buffer && size) buffer[total] = 0;
168  return total;
169 }
170 
171 
172 INFSTATUS
174  PCWSTR Section,
175  PCWSTR Key,
177 {
178  PINFCACHESECTION CacheSection;
179  PINFCACHELINE CacheLine;
180 
181  if (Cache == NULL || Section == NULL || Context == NULL)
182  {
183  DPRINT1("Invalid parameter\n");
185  }
186 
187  CacheSection = InfpFindSection(Cache, Section);
188  if (NULL == CacheSection)
189  {
190  DPRINT("Section not found\n");
191  return INF_STATUS_NOT_FOUND;
192  }
193 
194  if (Key != NULL)
195  {
196  CacheLine = InfpFindKeyLine(CacheSection, Key);
197  }
198  else
199  {
200  CacheLine = CacheSection->FirstLine;
201  }
202 
203  if (NULL == CacheLine)
204  {
205  DPRINT("Key not found\n");
206  return INF_STATUS_NOT_FOUND;
207  }
208 
209  *Context = MALLOC(sizeof(INFCONTEXT));
210  if (NULL == *Context)
211  {
212  DPRINT1("MALLOC() failed\n");
213  return INF_STATUS_NO_MEMORY;
214  }
215  (*Context)->Inf = (PVOID)Cache;
216  (*Context)->Section = (PVOID)CacheSection;
217  (*Context)->Line = (PVOID)CacheLine;
218 
219  return INF_STATUS_SUCCESS;
220 }
221 
222 
223 INFSTATUS
225  PINFCONTEXT ContextOut)
226 {
227  PINFCACHELINE CacheLine;
228 
229  if (ContextIn == NULL || ContextOut == NULL)
231 
232  if (ContextIn->Line == NULL)
234 
235  CacheLine = (PINFCACHELINE)ContextIn->Line;
236  if (CacheLine->Next == NULL)
237  return INF_STATUS_NOT_FOUND;
238 
239  if (ContextIn != ContextOut)
240  {
241  ContextOut->Inf = ContextIn->Inf;
242  ContextOut->Section = ContextIn->Section;
243  }
244  ContextOut->Line = (PVOID)(CacheLine->Next);
245 
246  return INF_STATUS_SUCCESS;
247 }
248 
249 
250 INFSTATUS
252  PCWSTR Key,
253  PINFCONTEXT ContextOut)
254 {
255  PINFCACHELINE CacheLine;
256 
257  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
259 
260  if (ContextIn->Inf == NULL || ContextIn->Section == NULL)
262 
263  CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine;
264  while (CacheLine != NULL)
265  {
266  if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
267  {
268 
269  if (ContextIn != ContextOut)
270  {
271  ContextOut->Inf = ContextIn->Inf;
272  ContextOut->Section = ContextIn->Section;
273  }
274  ContextOut->Line = (PVOID)CacheLine;
275 
276  return INF_STATUS_SUCCESS;
277  }
278 
279  CacheLine = CacheLine->Next;
280  }
281 
282  return INF_STATUS_NOT_FOUND;
283 }
284 
285 
286 INFSTATUS
288  PCWSTR Key,
289  PINFCONTEXT ContextOut)
290 {
291  PINFCACHELINE CacheLine;
292 
293  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
295 
296  if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL)
298 
299  CacheLine = (PINFCACHELINE)ContextIn->Line;
300  while (CacheLine != NULL)
301  {
302  if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
303  {
304 
305  if (ContextIn != ContextOut)
306  {
307  ContextOut->Inf = ContextIn->Inf;
308  ContextOut->Section = ContextIn->Section;
309  }
310  ContextOut->Line = (PVOID)CacheLine;
311 
312  return INF_STATUS_SUCCESS;
313  }
314 
315  CacheLine = CacheLine->Next;
316  }
317 
318  return INF_STATUS_NOT_FOUND;
319 }
320 
321 
322 LONG
324  PCWSTR Section)
325 {
327  PINFCACHESECTION CacheSection;
328 
329  if (InfHandle == NULL || Section == NULL)
330  {
331  DPRINT("Invalid parameter\n");
332  return -1;
333  }
334 
335  Cache = (PINFCACHE)InfHandle;
336 
337  /* Iterate through list of sections */
338  CacheSection = Cache->FirstSection;
339  while (CacheSection != NULL)
340  {
341  /* Are the section names the same? */
342  if (strcmpiW(CacheSection->Name, Section) == 0)
343  {
344  return CacheSection->LineCount;
345  }
346 
347  /* Get the next section */
348  CacheSection = CacheSection->Next;
349  }
350 
351  DPRINT("Section not found\n");
352 
353  return -1;
354 }
355 
356 
357 /* InfpGetLineText */
358 
359 
360 LONG
362 {
363  if (Context == NULL || Context->Line == NULL)
364  return 0;
365 
366  return ((PINFCACHELINE)Context->Line)->FieldCount;
367 }
368 
369 
370 INFSTATUS
373  PUCHAR ReturnBuffer,
376 {
377  PINFCACHELINE CacheLine;
378  PINFCACHEFIELD CacheField;
379  ULONG Index;
380  ULONG Size;
381  PUCHAR Ptr;
382 
383  if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
384  {
385  DPRINT("Invalid parameter\n");
387  }
388 
389  if (RequiredSize != NULL)
390  *RequiredSize = 0;
391 
392  CacheLine = (PINFCACHELINE)Context->Line;
393 
394  if (FieldIndex > (ULONG)CacheLine->FieldCount)
395  return INF_STATUS_NOT_FOUND;
396 
397  CacheField = CacheLine->FirstField;
398  for (Index = 1; Index < FieldIndex; Index++)
399  CacheField = CacheField->Next;
400 
401  Size = (ULONG)CacheLine->FieldCount - FieldIndex + 1;
402 
403  if (RequiredSize != NULL)
404  *RequiredSize = Size;
405 
406  if (ReturnBuffer != NULL)
407  {
408  if (ReturnBufferSize < Size)
410 
411  /* Copy binary data */
412  Ptr = ReturnBuffer;
413  while (CacheField != NULL)
414  {
415  *Ptr = (UCHAR)strtoulW(CacheField->Data, NULL, 16);
416 
417  Ptr++;
418  CacheField = CacheField->Next;
419  }
420  }
421 
422  return INF_STATUS_SUCCESS;
423 }
424 
425 
426 INFSTATUS
429  INT *IntegerValue)
430 {
431  PINFCACHELINE CacheLine;
432  PINFCACHEFIELD CacheField;
433  ULONG Index;
434  PWCHAR Ptr;
435 
436  if (Context == NULL || Context->Line == NULL || IntegerValue == NULL)
437  {
438  DPRINT("Invalid parameter\n");
440  }
441 
442  CacheLine = (PINFCACHELINE)Context->Line;
443 
444  if (FieldIndex > (ULONG)CacheLine->FieldCount)
445  {
446  DPRINT("Invalid parameter\n");
448  }
449 
450  if (FieldIndex == 0)
451  {
452  Ptr = CacheLine->Key;
453  }
454  else
455  {
456  CacheField = CacheLine->FirstField;
457  for (Index = 1; Index < FieldIndex; Index++)
458  CacheField = CacheField->Next;
459 
460  Ptr = CacheField->Data;
461  }
462 
463  *IntegerValue = (LONG)strtolW(Ptr, NULL, 0);
464 
465  return INF_STATUS_SUCCESS;
466 }
467 
468 
469 INFSTATUS
472  PWSTR ReturnBuffer,
475 {
476  PINFCACHELINE CacheLine;
477  PINFCACHEFIELD CacheField;
478  PINFCACHEFIELD FieldPtr;
479  ULONG Index;
480  ULONG Size;
481  PWCHAR Ptr;
482 
483  if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
484  {
485  DPRINT("Invalid parameter\n");
487  }
488 
489  if (RequiredSize != NULL)
490  *RequiredSize = 0;
491 
492  CacheLine = (PINFCACHELINE)Context->Line;
493 
494  if (FieldIndex > (ULONG)CacheLine->FieldCount)
496 
497  CacheField = CacheLine->FirstField;
498  for (Index = 1; Index < FieldIndex; Index++)
499  CacheField = CacheField->Next;
500 
501  /* Calculate the required buffer size */
502  FieldPtr = CacheField;
503  Size = 0;
504  while (FieldPtr != NULL)
505  {
506  Size += ((ULONG)strlenW(FieldPtr->Data) + 1);
507  FieldPtr = FieldPtr->Next;
508  }
509  Size++;
510 
511  if (RequiredSize != NULL)
512  *RequiredSize = Size;
513 
514  if (ReturnBuffer != NULL)
515  {
516  if (ReturnBufferSize < Size)
518 
519  /* Copy multi-sz string */
520  Ptr = ReturnBuffer;
521  FieldPtr = CacheField;
522  while (FieldPtr != NULL)
523  {
524  Size = (ULONG)strlenW(FieldPtr->Data) + 1;
525 
526  strcpyW(Ptr, FieldPtr->Data);
527 
528  Ptr = Ptr + Size;
529  FieldPtr = FieldPtr->Next;
530  }
531  *Ptr = 0;
532  }
533 
534  return INF_STATUS_SUCCESS;
535 }
536 
537 
538 INFSTATUS
541  PWSTR ReturnBuffer,
544 {
545  PINFCACHELINE CacheLine;
546  PINFCACHEFIELD CacheField;
547  ULONG Index;
548  PWCHAR Ptr;
549  SIZE_T Size;
550 
551  if (Context == NULL || Context->Line == NULL)
552  {
553  DPRINT("Invalid parameter\n");
555  }
556 
557  if (RequiredSize != NULL)
558  *RequiredSize = 0;
559 
560  CacheLine = (PINFCACHELINE)Context->Line;
561 
562  if (FieldIndex > (ULONG)CacheLine->FieldCount)
564 
565  if (FieldIndex == 0)
566  {
567  Ptr = CacheLine->Key;
568  }
569  else
570  {
571  CacheField = CacheLine->FirstField;
572  for (Index = 1; Index < FieldIndex; Index++)
573  CacheField = CacheField->Next;
574 
575  Ptr = CacheField->Data;
576  }
577 
578 // Size = (ULONG)strlenW(Ptr) + 1;
580  Ptr,
581  NULL,
582  0);
583 
584  if (RequiredSize != NULL)
585  *RequiredSize = Size + 1;
586 
587  if (ReturnBuffer != NULL)
588  {
589  if (ReturnBufferSize <= Size)
591 
592 // strcpyW(ReturnBuffer, Ptr);
594  Ptr,
595  ReturnBuffer,
597  }
598 
599  return INF_STATUS_SUCCESS;
600 }
601 
602 
603 INFSTATUS
605  PWCHAR *Key,
606  PWCHAR *Data)
607 {
608  PINFCACHELINE CacheKey;
609 
610  if (Context == NULL || Context->Line == NULL || Data == NULL)
611  {
612  DPRINT("Invalid parameter\n");
614  }
615 
616  CacheKey = (PINFCACHELINE)Context->Line;
617  if (Key != NULL)
618  *Key = CacheKey->Key;
619 
620  if (Data != NULL)
621  {
622  if (CacheKey->FirstField == NULL)
623  {
624  *Data = NULL;
625  }
626  else
627  {
628  *Data = CacheKey->FirstField->Data;
629  }
630  }
631 
632  return INF_STATUS_SUCCESS;
633 }
634 
635 
636 INFSTATUS
639  PWCHAR *Data)
640 {
641  PINFCACHELINE CacheLine;
642  PINFCACHEFIELD CacheField;
643  ULONG Index;
644 
645  if (Context == NULL || Context->Line == NULL || Data == NULL)
646  {
647  DPRINT("Invalid parameter\n");
649  }
650 
651  CacheLine = (PINFCACHELINE)Context->Line;
652 
653  if (FieldIndex > (ULONG)CacheLine->FieldCount)
655 
656  if (FieldIndex == 0)
657  {
658  *Data = CacheLine->Key;
659  }
660  else
661  {
662  CacheField = CacheLine->FirstField;
663  for (Index = 1; Index < FieldIndex; Index++)
664  CacheField = CacheField->Next;
665 
666  *Data = CacheField->Data;
667  }
668 
669  return INF_STATUS_SUCCESS;
670 }
671 
672 VOID
674 {
675  FREE(Context);
676 }
677 
678 /* EOF */
LONG LineCount
Definition: inffile.c:75
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
const uint16_t * PCWSTR
Definition: typedefs.h:55
INFSTATUS InfpGetBinaryField(PINFCONTEXT Context, ULONG FieldIndex, PUCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:371
CHAR Name[1]
Definition: inffile.c:77
#define MALLOC(Size)
Definition: builddep.h:73
struct _INFCACHESECTION * PINFCACHESECTION
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
Definition: fatfs.h:173
struct _INFCACHELINE * PINFCACHELINE
uint16_t * PWSTR
Definition: typedefs.h:54
const WCHAR * text
Definition: package.c:1827
struct _INFCACHEFIELD * Next
Definition: inffile.c:47
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define strtolW(s, e, b)
Definition: unicode.h:33
ULONG FieldCount
Definition: inffile.c:58
INFSTATUS InfpFindFirstLine(PINFCACHE Cache, PCWSTR Section, PCWSTR Key, PINFCONTEXT *Context)
Definition: infget.c:173
LANGID LanguageId
Definition: infpriv.h:58
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1891
GLuint buffer
Definition: glext.h:5915
#define INF_STATUS_NO_MEMORY
Definition: builddep.h:78
INFSTATUS InfpGetData(PINFCONTEXT Context, PWCHAR *Key, PWCHAR *Data)
Definition: infget.c:604
uint16_t * PWCHAR
Definition: typedefs.h:54
#define SUBLANG_NEUTRAL
Definition: nls.h:167
INFSTATUS InfpGetStringField(PINFCONTEXT Context, ULONG FieldIndex, PWSTR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:539
INFSTATUS InfpGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PWCHAR *Data)
Definition: infget.c:637
int INFSTATUS
Definition: infpriv.h:73
int32_t INT
Definition: typedefs.h:56
struct _INFCACHESECTION * Next
Definition: inffile.c:69
PINFCACHESECTION InfpFindSection(PINFCACHE Cache, PCWSTR Name)
Definition: infcore.c:143
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
while(1)
Definition: macro.lex.yy.c:740
PINFCACHELINE InfpFindKeyLine(PINFCACHESECTION Section, PCWSTR Key)
Definition: infcore.c:320
PINFCACHEFIELD FirstField
Definition: inffile.c:62
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static size_t InfpSubstituteString(PINFCACHE Inf, const WCHAR *text, WCHAR *buffer, size_t size)
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define INF_STATUS_BUFFER_OVERFLOW
Definition: builddep.h:81
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
static PCWSTR InfpGetSubstitutionString(PINFCACHE Inf, PCWSTR str, size_t *len, BOOL no_trailing_slash)
Definition: infget.c:37
void * PVOID
Definition: retypes.h:9
_Inout_ PRTL_BUFFER _In_ SIZE_T RequiredSize
INFSTATUS InfpFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: infget.c:224
GLsizeiptr size
Definition: glext.h:5919
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ DWORD FieldIndex
Definition: setupapi.h:1889
struct _INFCACHE * PINFCACHE
INFSTATUS InfpGetMultiSzField(PINFCONTEXT Context, ULONG FieldIndex, PWSTR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:470
static const UCHAR Index[8]
Definition: usbohci.c:18
INFSTATUS InfpFindNextMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:287
#define INF_STATUS_NOT_FOUND
Definition: builddep.h:80
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define FREE(ptr, size)
Definition: auth_des.c:64
CHAR Data[1]
Definition: inffile.c:50
#define INF_STATUS_INVALID_PARAMETER
Definition: builddep.h:79
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
LONG InfpGetFieldCount(PINFCONTEXT Context)
Definition: infget.c:361
Status
Definition: gdiplustypes.h:24
#define strcmpiW(s1, s2)
Definition: unicode.h:39
LONG InfpGetLineCount(HINF InfHandle, PCWSTR Section)
Definition: infget.c:323
PINFCACHELINE FirstLine
Definition: inffile.c:72
#define INF_STATUS_SUCCESS
Definition: builddep.h:77
static void ShortToHex(PWCHAR Buffer, USHORT Value)
Definition: infget.c:23
ULONG_PTR SIZE_T
Definition: typedefs.h:78
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
VOID InfpFreeContext(PINFCONTEXT Context)
Definition: infget.c:673
unsigned short USHORT
Definition: pedump.c:61
GLuint start
Definition: gl.h:1545
UINT Section
Definition: infsupp.h:26
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
struct _INFCACHELINE * Next
Definition: inffile.c:55
unsigned int ULONG
Definition: retypes.h:1
#define MAKELANGID(p, s)
Definition: nls.h:15
HINF Inf
Definition: infsupp.h:24
#define strtoulW(s1, s2, b)
Definition: unicode.h:41
GLfloat GLfloat p
Definition: glext.h:8902
return STATUS_SUCCESS
Definition: btrfs.c:2725
INFSTATUS InfpFindFirstMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:251
INFSTATUS InfpGetIntField(PINFCONTEXT Context, ULONG FieldIndex, INT *IntegerValue)
Definition: infget.c:427
UINT Line
Definition: infsupp.h:27
PCHAR Key
Definition: inffile.c:60
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define PRIMARYLANGID(l)
Definition: nls.h:16