ReactOS  0.4.14-dev-50-g13bb5e2
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 = CacheSection->Id;
217  (*Context)->Line = CacheLine->Id;
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  CacheLine = InfpGetLineForContext(ContextIn);
233  if (CacheLine == NULL)
235 
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 = CacheLine->Next->Id;
245 
246  return INF_STATUS_SUCCESS;
247 }
248 
249 
250 INFSTATUS
252  PCWSTR Key,
253  PINFCONTEXT ContextOut)
254 {
255  PINFCACHESECTION Section;
256  PINFCACHELINE CacheLine;
257 
258  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
260 
261  Section = InfpGetSectionForContext(ContextIn);
262  if (Section == NULL)
264 
265  CacheLine = Section->FirstLine;
266  while (CacheLine != NULL)
267  {
268  if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
269  {
270 
271  if (ContextIn != ContextOut)
272  {
273  ContextOut->Inf = ContextIn->Inf;
274  ContextOut->Section = ContextIn->Section;
275  }
276  ContextOut->Line = CacheLine->Id;
277 
278  return INF_STATUS_SUCCESS;
279  }
280 
281  CacheLine = CacheLine->Next;
282  }
283 
284  return INF_STATUS_NOT_FOUND;
285 }
286 
287 
288 INFSTATUS
290  PCWSTR Key,
291  PINFCONTEXT ContextOut)
292 {
293  PINFCACHESECTION Section;
294  PINFCACHELINE CacheLine;
295 
296  if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
298 
299  Section = InfpGetSectionForContext(ContextIn);
300  if (Section == NULL)
302 
303  CacheLine = InfpGetLineForContext(ContextIn);
304  while (CacheLine != NULL)
305  {
306  if (CacheLine->Key != NULL && strcmpiW (CacheLine->Key, Key) == 0)
307  {
308 
309  if (ContextIn != ContextOut)
310  {
311  ContextOut->Inf = ContextIn->Inf;
312  ContextOut->Section = ContextIn->Section;
313  }
314  ContextOut->Line = CacheLine->Id;
315 
316  return INF_STATUS_SUCCESS;
317  }
318 
319  CacheLine = CacheLine->Next;
320  }
321 
322  return INF_STATUS_NOT_FOUND;
323 }
324 
325 
326 LONG
328  PCWSTR Section)
329 {
331  PINFCACHESECTION CacheSection;
332 
333  if (InfHandle == NULL || Section == NULL)
334  {
335  DPRINT("Invalid parameter\n");
336  return -1;
337  }
338 
339  Cache = (PINFCACHE)InfHandle;
340 
341  /* Iterate through list of sections */
342  CacheSection = Cache->FirstSection;
343  while (CacheSection != NULL)
344  {
345  /* Are the section names the same? */
346  if (strcmpiW(CacheSection->Name, Section) == 0)
347  {
348  return CacheSection->LineCount;
349  }
350 
351  /* Get the next section */
352  CacheSection = CacheSection->Next;
353  }
354 
355  DPRINT("Section not found\n");
356 
357  return -1;
358 }
359 
360 
361 /* InfpGetLineText */
362 
363 
364 LONG
366 {
368 
370  if (Line == NULL)
371  return 0;
372  return Line->FieldCount;
373 }
374 
375 
376 INFSTATUS
379  PUCHAR ReturnBuffer,
382 {
383  PINFCACHELINE CacheLine;
384  PINFCACHEFIELD CacheField;
385  ULONG Index;
386  ULONG Size;
387  PUCHAR Ptr;
388 
389  if (Context == NULL || FieldIndex == 0)
390  {
391  DPRINT("Invalid parameter\n");
393  }
394 
395  if (RequiredSize != NULL)
396  *RequiredSize = 0;
397 
398  CacheLine = InfpGetLineForContext(Context);
399 
400  if (FieldIndex > (ULONG)CacheLine->FieldCount)
401  return INF_STATUS_NOT_FOUND;
402 
403  CacheField = CacheLine->FirstField;
404  for (Index = 1; Index < FieldIndex; Index++)
405  CacheField = CacheField->Next;
406 
407  Size = (ULONG)CacheLine->FieldCount - FieldIndex + 1;
408 
409  if (RequiredSize != NULL)
410  *RequiredSize = Size;
411 
412  if (ReturnBuffer != NULL)
413  {
414  if (ReturnBufferSize < Size)
416 
417  /* Copy binary data */
418  Ptr = ReturnBuffer;
419  while (CacheField != NULL)
420  {
421  *Ptr = (UCHAR)strtoulW(CacheField->Data, NULL, 16);
422 
423  Ptr++;
424  CacheField = CacheField->Next;
425  }
426  }
427 
428  return INF_STATUS_SUCCESS;
429 }
430 
431 
432 INFSTATUS
435  INT *IntegerValue)
436 {
437  PINFCACHELINE CacheLine;
438  PINFCACHEFIELD CacheField;
439  ULONG Index;
440  PWCHAR Ptr;
441 
442  if (Context == NULL || IntegerValue == NULL)
443  {
444  DPRINT("Invalid parameter\n");
446  }
447 
448  CacheLine = InfpGetLineForContext(Context);
449 
450  if (FieldIndex > (ULONG)CacheLine->FieldCount)
451  {
452  DPRINT("Invalid parameter\n");
454  }
455 
456  if (FieldIndex == 0)
457  {
458  Ptr = CacheLine->Key;
459  }
460  else
461  {
462  CacheField = CacheLine->FirstField;
463  for (Index = 1; Index < FieldIndex; Index++)
464  CacheField = CacheField->Next;
465 
466  Ptr = CacheField->Data;
467  }
468 
469  *IntegerValue = (LONG)strtolW(Ptr, NULL, 0);
470 
471  return INF_STATUS_SUCCESS;
472 }
473 
474 
475 INFSTATUS
478  PWSTR ReturnBuffer,
481 {
482  PINFCACHELINE CacheLine;
483  PINFCACHEFIELD CacheField;
484  PINFCACHEFIELD FieldPtr;
485  ULONG Index;
486  ULONG Size;
487  PWCHAR Ptr;
488 
489  if (Context == NULL || FieldIndex == 0)
490  {
491  DPRINT("Invalid parameter\n");
493  }
494 
495  if (RequiredSize != NULL)
496  *RequiredSize = 0;
497 
498  CacheLine = InfpGetLineForContext(Context);
499 
500  if (FieldIndex > (ULONG)CacheLine->FieldCount)
502 
503  CacheField = CacheLine->FirstField;
504  for (Index = 1; Index < FieldIndex; Index++)
505  CacheField = CacheField->Next;
506 
507  /* Calculate the required buffer size */
508  FieldPtr = CacheField;
509  Size = 0;
510  while (FieldPtr != NULL)
511  {
512  Size += ((ULONG)strlenW(FieldPtr->Data) + 1);
513  FieldPtr = FieldPtr->Next;
514  }
515  Size++;
516 
517  if (RequiredSize != NULL)
518  *RequiredSize = Size;
519 
520  if (ReturnBuffer != NULL)
521  {
522  if (ReturnBufferSize < Size)
524 
525  /* Copy multi-sz string */
526  Ptr = ReturnBuffer;
527  FieldPtr = CacheField;
528  while (FieldPtr != NULL)
529  {
530  Size = (ULONG)strlenW(FieldPtr->Data) + 1;
531 
532  strcpyW(Ptr, FieldPtr->Data);
533 
534  Ptr = Ptr + Size;
535  FieldPtr = FieldPtr->Next;
536  }
537  *Ptr = 0;
538  }
539 
540  return INF_STATUS_SUCCESS;
541 }
542 
543 
544 INFSTATUS
547  PWSTR ReturnBuffer,
550 {
551  PINFCACHELINE CacheLine;
552  PINFCACHEFIELD CacheField;
553  ULONG Index;
554  PWCHAR Ptr;
555  SIZE_T Size;
556 
557  if (Context == NULL)
558  {
559  DPRINT("Invalid parameter\n");
561  }
562 
563  if (RequiredSize != NULL)
564  *RequiredSize = 0;
565 
566  CacheLine = InfpGetLineForContext(Context);
567 
568  if (FieldIndex > (ULONG)CacheLine->FieldCount)
570 
571  if (FieldIndex == 0)
572  {
573  Ptr = CacheLine->Key;
574  }
575  else
576  {
577  CacheField = CacheLine->FirstField;
578  for (Index = 1; Index < FieldIndex; Index++)
579  CacheField = CacheField->Next;
580 
581  Ptr = CacheField->Data;
582  }
583 
584 // Size = (ULONG)strlenW(Ptr) + 1;
586  Ptr,
587  NULL,
588  0);
589 
590  if (RequiredSize != NULL)
591  *RequiredSize = (ULONG)Size + 1;
592 
593  if (ReturnBuffer != NULL)
594  {
595  if (ReturnBufferSize <= Size)
597 
598 // strcpyW(ReturnBuffer, Ptr);
600  Ptr,
601  ReturnBuffer,
603  }
604 
605  return INF_STATUS_SUCCESS;
606 }
607 
608 
609 INFSTATUS
611  PWCHAR *Key,
612  PWCHAR *Data)
613 {
614  PINFCACHELINE CacheKey;
615 
616  if (Context == NULL || Data == NULL)
617  {
618  DPRINT("Invalid parameter\n");
620  }
621 
622  CacheKey = InfpGetLineForContext(Context);
623  if (Key != NULL)
624  *Key = CacheKey->Key;
625 
626  if (Data != NULL)
627  {
628  if (CacheKey->FirstField == NULL)
629  {
630  *Data = NULL;
631  }
632  else
633  {
634  *Data = CacheKey->FirstField->Data;
635  }
636  }
637 
638  return INF_STATUS_SUCCESS;
639 }
640 
641 
642 INFSTATUS
645  PWCHAR *Data)
646 {
647  PINFCACHELINE CacheLine;
648  PINFCACHEFIELD CacheField;
649  ULONG Index;
650 
651  if (Context == NULL || Data == NULL)
652  {
653  DPRINT("Invalid parameter\n");
655  }
656 
657  CacheLine = InfpGetLineForContext(Context);
658 
659  if (FieldIndex > (ULONG)CacheLine->FieldCount)
661 
662  if (FieldIndex == 0)
663  {
664  *Data = CacheLine->Key;
665  }
666  else
667  {
668  CacheField = CacheLine->FirstField;
669  for (Index = 1; Index < FieldIndex; Index++)
670  CacheField = CacheField->Next;
671 
672  *Data = CacheField->Data;
673  }
674 
675  return INF_STATUS_SUCCESS;
676 }
677 
678 VOID
680 {
681  FREE(Context);
682 }
683 
684 /* EOF */
LONG LineCount
Definition: inffile.c:57
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
const uint16_t * PCWSTR
Definition: typedefs.h:55
INFSTATUS InfpGetBinaryField(PINFCONTEXT Context, ULONG FieldIndex, PUCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:377
CHAR Name[1]
Definition: inffile.c:59
#define MALLOC(Size)
Definition: builddep.h:73
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
Definition: fatfs.h:173
uint16_t * PWSTR
Definition: typedefs.h:54
const WCHAR * text
Definition: package.c:1827
struct _INFCACHEFIELD * Next
Definition: inffile.c:29
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:40
INFSTATUS InfpFindFirstLine(PINFCACHE Cache, PCWSTR Section, PCWSTR Key, PINFCONTEXT *Context)
Definition: infget.c:173
LANGID LanguageId
Definition: infpriv.h:61
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1892
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:610
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:545
INFSTATUS InfpGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PWCHAR *Data)
Definition: infget.c:643
int INFSTATUS
Definition: infpriv.h:77
int32_t INT
Definition: typedefs.h:56
struct _INFCACHESECTION * Next
Definition: inffile.c:51
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:390
PINFCACHEFIELD FirstField
Definition: inffile.c:44
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ DWORD FieldIndex
Definition: setupapi.h:1890
struct _INFCACHE * PINFCACHE
INFSTATUS InfpGetMultiSzField(PINFCONTEXT Context, ULONG FieldIndex, PWSTR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:476
static const UCHAR Index[8]
Definition: usbohci.c:18
INFSTATUS InfpFindNextMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:289
Definition: ncftp.h:79
#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:32
#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:365
Status
Definition: gdiplustypes.h:24
#define strcmpiW(s1, s2)
Definition: unicode.h:39
LONG InfpGetLineCount(HINF InfHandle, PCWSTR Section)
Definition: infget.c:327
PINFCACHELINE FirstLine
Definition: inffile.c:54
#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:679
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:37
PINFCACHELINE InfpGetLineForContext(PINFCONTEXT Context)
Definition: infcore.c:310
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:2966
INFSTATUS InfpFindFirstMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:251
INFSTATUS InfpGetIntField(PINFCONTEXT Context, ULONG FieldIndex, INT *IntegerValue)
Definition: infget.c:433
PINFCACHESECTION InfpGetSectionForContext(PINFCONTEXT Context)
Definition: infcore.c:273
UINT Line
Definition: infsupp.h:27
PCHAR Key
Definition: inffile.c:42
struct Line Line
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define PRIMARYLANGID(l)
Definition: nls.h:16