ReactOS 0.4.16-dev-297-gc569aee
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
16static size_t
18 const WCHAR *text,
20 size_t size);
21
22static void
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 */
36static PCWSTR
38 PCWSTR str,
39 size_t *len,
40 BOOL no_trailing_slash)
41{
42 static const WCHAR percent = '%';
43
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,
69 &Context);
71 {
72 ShortToHex(&StringLangId[sizeof("Strings.") - 1],
74
76 StringLangId,
78 &Context);
80 {
82 L"Strings",
84 &Context);
85 }
86 }
87 }
88 else
89 {
91 L"Strings",
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 */
119static size_t
121 PCWSTR text,
123 size_t size)
124{
125 const WCHAR *start, *subst, *p;
126 size_t len, total = 0;
127 int inside = 0;
128
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
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");
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");
207 }
208
209 *Context = MALLOC(sizeof(INFCONTEXT));
210 if (NULL == *Context)
211 {
212 DPRINT1("MALLOC() failed\n");
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
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)
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
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
285}
286
287
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
323}
324
325
326LONG
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
364LONG
366{
368
370 if (Line == NULL)
371 return 0;
372 return Line->FieldCount;
373}
374
375
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)
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)
411
412 if (ReturnBuffer != NULL)
413 {
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
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
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)
519
520 if (ReturnBuffer != NULL)
521 {
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
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
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
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
678VOID
680{
681 FREE(Context);
682}
683
684/* EOF */
#define FREE(ptr, size)
Definition: auth_des.c:64
#define DPRINT1
Definition: precomp.h:8
#define MALLOC(Size)
Definition: builddep.h:73
#define INF_STATUS_INVALID_PARAMETER
Definition: builddep.h:79
#define INF_STATUS_SUCCESS
Definition: builddep.h:77
#define INF_STATUS_NO_MEMORY
Definition: builddep.h:78
#define INF_STATUS_NOT_FOUND
Definition: builddep.h:80
#define INF_STATUS_BUFFER_OVERFLOW
Definition: builddep.h:81
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
const WCHAR * text
Definition: package.c:1794
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned int BOOL
Definition: ntddk_ex.h:94
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
size_t total
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
PINFCACHESECTION InfpFindSection(PINFCACHE Cache, PCWSTR Name)
Definition: infcore.c:143
PINFCACHELINE InfpGetLineForContext(PINFCONTEXT Context)
Definition: infcore.c:310
PINFCACHELINE InfpFindKeyLine(PINFCACHESECTION Section, PCWSTR Key)
Definition: infcore.c:390
PINFCACHESECTION InfpGetSectionForContext(PINFCONTEXT Context)
Definition: infcore.c:273
struct _INFCACHE * PINFCACHE
INFSTATUS InfpGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PWCHAR *Data)
Definition: infget.c:643
INFSTATUS InfpGetIntField(PINFCONTEXT Context, ULONG FieldIndex, INT *IntegerValue)
Definition: infget.c:433
INFSTATUS InfpFindFirstMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:251
INFSTATUS InfpFindFirstLine(PINFCACHE Cache, PCWSTR Section, PCWSTR Key, PINFCONTEXT *Context)
Definition: infget.c:173
VOID InfpFreeContext(PINFCONTEXT Context)
Definition: infget.c:679
INFSTATUS InfpGetStringField(PINFCONTEXT Context, ULONG FieldIndex, PWSTR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:545
LONG InfpGetLineCount(HINF InfHandle, PCWSTR Section)
Definition: infget.c:327
LONG InfpGetFieldCount(PINFCONTEXT Context)
Definition: infget.c:365
INFSTATUS InfpGetData(PINFCONTEXT Context, PWCHAR *Key, PWCHAR *Data)
Definition: infget.c:610
INFSTATUS InfpGetMultiSzField(PINFCONTEXT Context, ULONG FieldIndex, PWSTR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:476
INFSTATUS InfpFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: infget.c:224
INFSTATUS InfpGetBinaryField(PINFCONTEXT Context, ULONG FieldIndex, PUCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: infget.c:377
static PCWSTR InfpGetSubstitutionString(PINFCACHE Inf, PCWSTR str, size_t *len, BOOL no_trailing_slash)
Definition: infget.c:37
INFSTATUS InfpFindNextMatchLine(PINFCONTEXT ContextIn, PCWSTR Key, PINFCONTEXT ContextOut)
Definition: infget.c:289
static size_t InfpSubstituteString(PINFCACHE Inf, const WCHAR *text, WCHAR *buffer, size_t size)
static void ShortToHex(PWCHAR Buffer, USHORT Value)
Definition: infget.c:23
int INFSTATUS
Definition: infpriv.h:77
#define MAX_INF_STRING_LENGTH
Definition: infsupp.h:34
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define strlenW(s)
Definition: unicode.h:34
#define strtoulW(s1, s2, b)
Definition: unicode.h:47
#define strtolW(s, e, b)
Definition: unicode.h:39
#define strcpyW(d, s)
Definition: unicode.h:35
const WCHAR * str
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_NEUTRAL
Definition: nls.h:167
#define PRIMARYLANGID(l)
Definition: nls.h:16
_In_ DWORD FieldIndex
Definition: setupapi.h:1895
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1897
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
Definition: fatfs.h:173
Definition: ncftp.h:79
struct _INFCACHEFIELD * Next
Definition: inffile.c:29
CHAR Data[1]
Definition: inffile.c:32
PINFCACHEFIELD FirstField
Definition: inffile.c:44
ULONG FieldCount
Definition: inffile.c:40
PCHAR Key
Definition: inffile.c:42
struct _INFCACHELINE * Next
Definition: inffile.c:37
struct _INFCACHESECTION * Next
Definition: inffile.c:51
PINFCACHELINE FirstLine
Definition: inffile.c:54
CHAR Name[1]
Definition: inffile.c:59
LONG LineCount
Definition: inffile.c:57
LANGID LanguageId
Definition: infpriv.h:61
HINF Inf
Definition: infsupp.h:24
UINT Line
Definition: infsupp.h:27
UINT Section
Definition: infsupp.h:26
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180