ReactOS 0.4.15-dev-8428-g6910fa6
inffile.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: INF file parser that caches contents of INF file in memory.
5 * COPYRIGHT: Copyright 2002-2006 Royce Mitchell III
6 * Copyright 2003-2019 Eric Kohl
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <freeldr.h>
12#include "inffile.h"
13
14#define CONTROL_Z '\x1a'
15#define MAX_SECTION_NAME_LEN 255
16#define MAX_FIELD_LEN 511 /* larger fields get silently truncated */
17/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */
18#define MAX_STRING_LEN (MAX_INF_STRING_LENGTH+1)
19
20#define TAG_INF_KEY 'KfnI'
21#define TAG_INF_FIELD 'ffnI'
22#define TAG_INF_LINE 'LfnI'
23#define TAG_INF_SECTION 'SfnI'
24#define TAG_INF_CACHE 'CfnI'
25#define TAG_INF_FILE 'FfnI'
26
27typedef struct _INFCACHEFIELD
28{
31
34
35typedef struct _INFCACHELINE
36{
39
41
43
46
48
49typedef struct _INFCACHESECTION
50{
53
56
58
61
62typedef struct _INFCACHE
63{
66
69
70/* parser definitions */
72{
73 LINE_START, /* at beginning of a line */
74 SECTION_NAME, /* parsing a section name */
75 KEY_NAME, /* parsing a key name */
76 VALUE_NAME, /* parsing a value name */
77 EOL_BACKSLASH, /* backslash at end of line */
78 QUOTES, /* inside quotes */
79 LEADING_SPACES, /* leading spaces */
80 TRAILING_SPACES, /* trailing spaces */
81 COMMENT, /* inside a comment */
83};
84
85struct parser
86{
87 const CHAR *start; /* start position of item being parsed */
88 const CHAR *end; /* end of buffer */
89 PINFCACHE file; /* file being built */
90 enum parser_state state; /* current parser state */
91 enum parser_state stack[4]; /* state stack */
92 int stack_pos; /* current pos in stack */
93
94 PINFCACHESECTION cur_section; /* pointer to the section being parsed*/
95 PINFCACHELINE line; /* current line */
96 unsigned int line_pos; /* current line position in file */
97 unsigned int error; /* error code */
98 unsigned int token_len; /* current token len */
99 CHAR token[MAX_FIELD_LEN + 1]; /* current token */
100};
101
102typedef const CHAR * (*parser_state_func)(struct parser *parser, const CHAR *pos);
103
104/* parser state machine functions */
105static const CHAR *line_start_state(struct parser *parser, const CHAR *pos);
106static const CHAR *section_name_state(struct parser *parser, const CHAR *pos);
107static const CHAR *key_name_state(struct parser *parser, const CHAR *pos);
108static const CHAR *value_name_state(struct parser *parser, const CHAR *pos);
109static const CHAR *eol_backslash_state(struct parser *parser, const CHAR *pos);
110static const CHAR *quotes_state(struct parser *parser, const CHAR *pos);
111static const CHAR *leading_spaces_state(struct parser *parser, const CHAR *pos);
112static const CHAR *trailing_spaces_state(struct parser *parser, const CHAR *pos);
113static const CHAR *comment_state(struct parser *parser, const CHAR *pos);
114
115static
118{
119 line_start_state, /* LINE_START */
120 section_name_state, /* SECTION_NAME */
121 key_name_state, /* KEY_NAME */
122 value_name_state, /* VALUE_NAME */
123 eol_backslash_state, /* EOL_BACKSLASH */
124 quotes_state, /* QUOTES */
125 leading_spaces_state, /* LEADING_SPACES */
126 trailing_spaces_state, /* TRAILING_SPACES */
127 comment_state /* COMMENT */
128};
129
130
131/* PRIVATE FUNCTIONS ********************************************************/
132
133static
137{
138 PINFCACHELINE Next;
139 PINFCACHEFIELD Field;
140
141 if (Line == NULL)
142 {
143 return NULL;
144 }
145
146 Next = Line->Next;
147 if (Line->Key != NULL)
148 {
150 Line->Key = NULL;
151 }
152
153 /* Remove data fields */
154 while (Line->FirstField != NULL)
155 {
156 Field = Line->FirstField->Next;
157 FrLdrTempFree(Line->FirstField, TAG_INF_FIELD);
158 Line->FirstField = Field;
159 }
160 Line->LastField = NULL;
161
163
164 return Next;
165}
166
167
168static
171 PINFCACHESECTION Section)
172{
173 PINFCACHESECTION Next;
174
175 if (Section == NULL)
176 {
177 return NULL;
178 }
179
180 /* Release all keys */
181 Next = Section->Next;
182 while (Section->FirstLine != NULL)
183 {
184 Section->FirstLine = InfpCacheFreeLine(Section->FirstLine);
185 }
186 Section->LastLine = NULL;
187
189
190 return Next;
191}
192
193
194static
198 PCSTR Name)
199{
200 PINFCACHESECTION Section = NULL;
201
202 if (Cache == NULL || Name == NULL)
203 {
204 return NULL;
205 }
206
207 /* iterate through list of sections */
208 Section = Cache->FirstSection;
209 while (Section != NULL)
210 {
211 if (_stricmp(Section->Name, Name) == 0)
212 {
213 return Section;
214 }
215
216 /* get the next section*/
217 Section = Section->Next;
218 }
219
220 return NULL;
221}
222
223
224static
228 PCSTR Name)
229{
230 PINFCACHESECTION Section = NULL;
231 SIZE_T Size;
232
233 if ((Cache == NULL) || (Name == NULL))
234 {
235// DPRINT("Invalid parameter\n");
236 return NULL;
237 }
238
239 /* Allocate and initialize the new section */
240 Size = sizeof(INFCACHESECTION) + strlen(Name);
242 if (Section == NULL)
243 {
244// DPRINT("RtlAllocateHeap() failed\n");
245 return NULL;
246 }
247 memset(Section, 0, Size);
248
249 /* Copy section name */
250 strcpy(Section->Name, Name);
251
252 /* Append section */
253 if (Cache->FirstSection == NULL)
254 {
255 Cache->FirstSection = Section;
256 Cache->LastSection = Section;
257 }
258 else
259 {
260 Cache->LastSection->Next = Section;
261 Section->Prev = Cache->LastSection;
262 Cache->LastSection = Section;
263 }
264
265 return Section;
266}
267
268
269static
272{
274
275 if (Section == NULL)
276 {
277// DPRINT("Invalid parameter\n");
278 return NULL;
279 }
280
282 if (Line == NULL)
283 {
284// DPRINT("RtlAllocateHeap() failed\n");
285 return NULL;
286 }
287 memset(Line, 0, sizeof(INFCACHELINE));
288
289 /* Append line */
290 if (Section->FirstLine == NULL)
291 {
292 Section->FirstLine = Line;
293 Section->LastLine = Line;
294 }
295 else
296 {
297 Section->LastLine->Next = Line;
298 Line->Prev = Section->LastLine;
299 Section->LastLine = Line;
300 }
301 Section->LineCount++;
302
303 return Line;
304}
305
306
307static
308PVOID
311 PCSTR Key)
312{
313 if (Line == NULL)
314 return NULL;
315
316 if (Line->Key != NULL)
317 return NULL;
318
320 if (Line->Key == NULL)
321 return NULL;
322
323 strcpy(Line->Key, Key);
324
325 return (PVOID)Line->Key;
326}
327
328
329static
330PVOID
333 PCSTR Data)
334{
335 PINFCACHEFIELD Field;
336 SIZE_T Size;
337
338 Size = sizeof(INFCACHEFIELD) + strlen(Data);
340 if (Field == NULL)
341 {
342 return NULL;
343 }
344 memset(Field, 0, Size);
345
346 strcpy(Field->Data, Data);
347
348 /* Append key */
349 if (Line->FirstField == NULL)
350 {
351 Line->FirstField = Field;
352 Line->LastField = Field;
353 }
354 else
355 {
356 Line->LastField->Next = Field;
357 Field->Prev = Line->LastField;
358 Line->LastField = Field;
359 }
360 Line->FieldCount++;
361
362 return (PVOID)Field;
363}
364
365
366static
369 PINFCACHESECTION Section,
370 PCSTR Key)
371{
373
374 Line = Section->FirstLine;
375 while (Line != NULL)
376 {
377 if ((Line->Key != NULL) && (_stricmp(Line->Key, Key) == 0))
378 {
379 return Line;
380 }
381
382 Line = Line->Next;
383 }
384
385 return NULL;
386}
387
388
389/* push the current state on the parser stack */
390__inline static void push_state(struct parser *parser, enum parser_state state)
391{
392// assert(parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]));
394}
395
396
397/* pop the current state */
398__inline static void pop_state(struct parser *parser)
399{
400// assert( parser->stack_pos );
402}
403
404
405/* set the parser state and return the previous one */
406__inline static enum parser_state set_state(struct parser *parser, enum parser_state state)
407{
409 parser->state = state;
410 return ret;
411}
412
413
414/* check if the pointer points to an end of file */
415__inline static int is_eof(struct parser *parser, const CHAR *ptr)
416{
417 return (ptr >= parser->end || *ptr == CONTROL_Z);
418}
419
420
421/* check if the pointer points to an end of line */
422__inline static int is_eol(struct parser *parser, const CHAR *ptr)
423{
424 return ((ptr >= parser->end) ||
425 (*ptr == CONTROL_Z) ||
426 (*ptr == '\n') ||
427 ((*ptr == '\r') && (*(ptr + 1) == '\n')));
428}
429
430
431/* push data from current token start up to pos into the current token */
432static
433int
435 struct parser *parser,
436 const CHAR *pos)
437{
439 const CHAR *src = parser->start;
441
444
446 for ( ; len > 0; len--, dst++, src++)
447 *dst = *src ? (CHAR)*src : L' ';
448 *dst = 0;
449 parser->start = pos;
450
451 return 0;
452}
453
454
455/* add a section with the current token as name */
456static
457PVOID
459{
460 PINFCACHESECTION Section;
461
463 {
464 parser->error = FALSE;
465 return NULL;
466 }
467
469 if (Section == NULL)
470 {
471 /* need to create a new one */
473 if (Section == NULL)
474 {
475 parser->error = FALSE;
476 return NULL;
477 }
478 }
479
480 parser->token_len = 0;
481 parser->cur_section = Section;
482
483 return (PVOID)Section;
484}
485
486
487/* add a field containing the current token to the current line */
488static
489struct field*
491 struct parser *parser,
492 int is_key)
493{
494 PVOID field;
495
496 if (!parser->line) /* need to start a new line */
497 {
498 if (parser->cur_section == NULL) /* got a line before the first section */
499 {
501 return NULL;
502 }
503
505 if (parser->line == NULL)
506 goto error;
507 }
508 else
509 {
510// assert(!is_key);
511 }
512
513 if (is_key)
514 {
516 }
517 else
518 {
520 }
521
522 if (field != NULL)
523 {
524 parser->token_len = 0;
525 return field;
526 }
527
528error:
529 parser->error = FALSE;
530 return NULL;
531}
532
533
534/* close the current line and prepare for parsing a new one */
535static
536VOID
538{
539 parser->line = NULL;
540}
541
542
543/* handler for parser LINE_START state */
544static
545const CHAR*
547 struct parser *parser,
548 const CHAR *pos)
549{
550 const CHAR *p;
551
552 for (p = pos; !is_eof(parser, p); p++)
553 {
554 switch(*p)
555 {
556 case '\r':
557 continue;
558
559 case '\n':
560 parser->line_pos++;
562 break;
563
564 case ';':
567 return p + 1;
568
569 case '[':
570 parser->start = p + 1;
572 return p + 1;
573
574 default:
575 if (!isspace((unsigned char)*p))
576 {
577 parser->start = p;
579 return p;
580 }
581 break;
582 }
583 }
585 return NULL;
586}
587
588
589/* handler for parser SECTION_NAME state */
590static
591const CHAR*
593 struct parser *parser,
594 const CHAR *pos)
595{
596 const CHAR *p;
597
598 for (p = pos; !is_eol(parser, p); p++)
599 {
600 if (*p == ']')
601 {
604 return NULL;
606 set_state(parser, COMMENT); /* ignore everything else on the line */
607 return p + 1;
608 }
609 }
610 parser->error = STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */
611 return NULL;
612}
613
614
615/* handler for parser KEY_NAME state */
616static
617const CHAR*
619 struct parser *parser,
620 const CHAR *pos)
621{
622 const CHAR *p, *token_end = parser->start;
623
624 for (p = pos; !is_eol(parser, p); p++)
625 {
626 if (*p == ',') break;
627 switch(*p)
628 {
629
630 case '=':
631 push_token(parser, token_end);
632 if (!add_field_from_token(parser, 1)) return NULL;
633 parser->start = p + 1;
636 return p + 1;
637 case ';':
638 push_token(parser, token_end);
639 if (!add_field_from_token(parser, 0)) return NULL;
642 return p + 1;
643 case '"':
644 push_token(parser, token_end);
645 parser->start = p + 1;
648 return p + 1;
649 case '\\':
650 push_token(parser, token_end);
651 parser->start = p;
654 return p;
655 default:
656 if (!isspace((unsigned char)*p)) token_end = p + 1;
657 else
658 {
662 return p;
663 }
664 break;
665 }
666 }
667 push_token(parser, token_end);
669 return p;
670}
671
672
673/* handler for parser VALUE_NAME state */
674static
675const CHAR*
677 struct parser *parser,
678 const CHAR *pos)
679{
680 const CHAR *p, *token_end = parser->start;
681
682 for (p = pos; !is_eol(parser, p); p++)
683 {
684 switch(*p)
685 {
686 case ';':
687 push_token(parser, token_end);
688 if (!add_field_from_token(parser, 0)) return NULL;
691 return p + 1;
692 case ',':
693 push_token(parser, token_end);
694 if (!add_field_from_token(parser, 0)) return NULL;
695 parser->start = p + 1;
698 return p + 1;
699 case '"':
700 push_token(parser, token_end);
701 parser->start = p + 1;
704 return p + 1;
705 case '\\':
706 push_token(parser, token_end);
707 parser->start = p;
710 return p;
711 default:
712 if (!isspace((unsigned char)*p)) token_end = p + 1;
713 else
714 {
718 return p;
719 }
720 break;
721 }
722 }
723 push_token(parser, token_end);
724 if (!add_field_from_token(parser, 0)) return NULL;
726 return p;
727}
728
729
730/* handler for parser EOL_BACKSLASH state */
731static
732const CHAR*
734 struct parser *parser,
735 const CHAR *pos )
736{
737 const CHAR *p;
738
739 for (p = pos; !is_eof(parser, p); p++)
740 {
741 switch(*p)
742 {
743 case '\r':
744 continue;
745
746 case '\n':
747 parser->line_pos++;
748 parser->start = p + 1;
750 return p + 1;
751
752 case '\\':
753 continue;
754
755 case ';':
758 return p + 1;
759
760 default:
761 if (isspace((unsigned char)*p))
762 continue;
765 return p;
766 }
767 }
768 parser->start = p;
770
771 return p;
772}
773
774
775/* handler for parser QUOTES state */
776static
777const CHAR*
779 struct parser *parser,
780 const CHAR *pos )
781{
782 const CHAR *p, *token_end = parser->start;
783
784 for (p = pos; !is_eol(parser, p); p++)
785 {
786 if (*p == '"')
787 {
788 if (p + 1 < parser->end && p[1] == '"') /* double quotes */
789 {
790 push_token(parser, p + 1);
791 parser->start = token_end = p + 2;
792 p++;
793 }
794 else /* end of quotes */
795 {
797 parser->start = p + 1;
799 return p + 1;
800 }
801 }
802 }
805 return p;
806}
807
808
809/* handler for parser LEADING_SPACES state */
810static
811const CHAR*
813 struct parser *parser,
814 const CHAR *pos )
815{
816 const CHAR *p;
817
818 for (p = pos; !is_eol(parser, p); p++)
819 {
820 if (*p == '\\')
821 {
822 parser->start = p;
824 return p;
825 }
826 if (!isspace((unsigned char)*p))
827 break;
828 }
829 parser->start = p;
831 return p;
832}
833
834
835/* handler for parser TRAILING_SPACES state */
836static
837const CHAR*
839 struct parser *parser,
840 const CHAR *pos )
841{
842 const CHAR *p;
843
844 for (p = pos; !is_eol(parser, p); p++)
845 {
846 if (*p == '\\')
847 {
849 return p;
850 }
851 if (!isspace((unsigned char)*p))
852 break;
853 }
855 return p;
856}
857
858
859/* handler for parser COMMENT state */
860static
861const CHAR*
863 struct parser *parser,
864 const CHAR *pos )
865{
866 const CHAR *p = pos;
867
868 while (!is_eol(parser, p))
869 p++;
871 return p;
872}
873
874
875/* parse a complete buffer */
876static
880 PCCHAR buffer,
881 PCCHAR end,
882 PULONG error_line)
883{
884 struct parser parser;
885 const CHAR* pos = buffer;
886
888 parser.end = end;
889 parser.file = file;
890 parser.line = NULL;
892 parser.stack_pos = 0;
894 parser.line_pos = 1;
895 parser.error = TRUE;
896 parser.token_len = 0;
897
898 /* parser main loop */
899 while (pos)
901
902 if (parser.error)
903 {
904 if (error_line)
905 *error_line = parser.line_pos;
906 return parser.error;
907 }
908
909 /* find the [strings] section */
910 file->StringsSection = InfpCacheFindSection(file, "Strings");
911
912 return TRUE;
913}
914
915/* PUBLIC FUNCTIONS *********************************************************/
916
919 PHINF InfHandle,
921 PULONG ErrorLine)
922{
924 ULONG FileId;
925 PCHAR FileBuffer;
930
931 *InfHandle = NULL;
932 *ErrorLine = (ULONG) - 1;
933
934 //
935 // Open the .inf file
936 //
938 if (Status != ESUCCESS)
939 {
940 return FALSE;
941 }
942
943 //
944 // Query file size
945 //
947 if ((Status != ESUCCESS) || (Information.EndingAddress.HighPart != 0))
948 {
949 ArcClose(FileId);
950 return FALSE;
951 }
952 FileSize = Information.EndingAddress.LowPart;
953
954 //
955 // Allocate buffer to cache the file
956 //
957 FileBuffer = FrLdrTempAlloc(FileSize + 1, TAG_INF_FILE);
958 if (!FileBuffer)
959 {
960 ArcClose(FileId);
961 return FALSE;
962 }
963
964 //
965 // Read file into memory
966 //
967 Status = ArcRead(FileId, FileBuffer, FileSize, &Count);
968 if ((Status != ESUCCESS) || (Count != FileSize))
969 {
970 ArcClose(FileId);
971 FrLdrTempFree(FileBuffer, TAG_INF_FILE);
972 return FALSE;
973 }
974
975 //
976 // We don't need the file anymore. Close it
977 //
978 ArcClose(FileId);
979
980 //
981 // Append string terminator
982 //
983 FileBuffer[FileSize] = 0;
984
985 //
986 // Allocate infcache header
987 //
989 if (!Cache)
990 {
991 FrLdrTempFree(FileBuffer, TAG_INF_FILE);
992 return FALSE;
993 }
994
995 //
996 // Initialize inicache header
997 //
998 RtlZeroMemory(Cache, sizeof(INFCACHE));
999
1000 //
1001 // Parse the inf buffer
1002 //
1004 FileBuffer,
1005 FileBuffer + FileSize,
1006 ErrorLine);
1007 if (!Success)
1008 {
1010 Cache = NULL;
1011 }
1012
1013 //
1014 // Free file buffer, as it has been parsed
1015 //
1016 FrLdrTempFree(FileBuffer, TAG_INF_FILE);
1017
1018 //
1019 // Return .inf parsed contents
1020 //
1021 *InfHandle = (HINF)Cache;
1022
1023 return Success;
1024}
1025
1026
1027VOID
1029{
1031
1032 Cache = (PINFCACHE)InfHandle;
1033
1034 if (Cache == NULL)
1035 {
1036 return;
1037 }
1038
1039 while (Cache->FirstSection != NULL)
1040 {
1041 Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
1042 }
1043 Cache->LastSection = NULL;
1044
1046}
1047
1048
1049BOOLEAN
1051 HINF InfHandle,
1052 PCSTR Section,
1053 PCSTR Key,
1055{
1057 PINFCACHESECTION CacheSection;
1058 PINFCACHELINE CacheLine;
1059
1060 if ((InfHandle == NULL) || (Section == NULL) || (Context == NULL))
1061 {
1062// DPRINT("Invalid parameter\n");
1063 return FALSE;
1064 }
1065
1066 Cache = (PINFCACHE)InfHandle;
1067
1068 /* Iterate through list of sections */
1069 CacheSection = Cache->FirstSection;
1070 while (CacheSection != NULL)
1071 {
1072// DPRINT("Comparing '%s' and '%s'\n", CacheSection->Name, Section);
1073
1074 /* Are the section names the same? */
1075 if (_stricmp(CacheSection->Name, Section) == 0)
1076 {
1077 if (Key != NULL)
1078 {
1079 CacheLine = InfpCacheFindKeyLine(CacheSection, Key);
1080 }
1081 else
1082 {
1083 CacheLine = CacheSection->FirstLine;
1084 }
1085
1086 if (CacheLine == NULL)
1087 return FALSE;
1088
1089 Context->Inf = (PVOID)Cache;
1090 Context->Section = (PVOID)CacheSection;
1091 Context->Line = (PVOID)CacheLine;
1092
1093 return TRUE;
1094 }
1095
1096 /* Get the next section */
1097 CacheSection = CacheSection->Next;
1098 }
1099
1100// DPRINT("Section not found\n");
1101
1102 return FALSE;
1103}
1104
1105
1106BOOLEAN
1108 PINFCONTEXT ContextIn,
1109 PINFCONTEXT ContextOut)
1110{
1111 PINFCACHELINE CacheLine;
1112
1113 if ((ContextIn == NULL) || (ContextOut == NULL))
1114 return FALSE;
1115
1116 if (ContextIn->Line == NULL)
1117 return FALSE;
1118
1119 CacheLine = (PINFCACHELINE)ContextIn->Line;
1120 if (CacheLine->Next == NULL)
1121 return FALSE;
1122
1123 if (ContextIn != ContextOut)
1124 {
1125 ContextOut->Inf = ContextIn->Inf;
1126 ContextOut->Section = ContextIn->Section;
1127 }
1128 ContextOut->Line = (PVOID)(CacheLine->Next);
1129
1130 return TRUE;
1131}
1132
1133
1134BOOLEAN
1136 PINFCONTEXT ContextIn,
1137 PCSTR Key,
1138 PINFCONTEXT ContextOut)
1139{
1140 PINFCACHELINE CacheLine;
1141
1142 if ((ContextIn == NULL) || (ContextOut == NULL) || (Key == NULL) || (*Key == 0))
1143 return FALSE;
1144
1145 if (ContextIn->Inf == NULL || ContextIn->Section == NULL)
1146 return FALSE;
1147
1148 CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine;
1149 while (CacheLine != NULL)
1150 {
1151 if ((CacheLine->Key != NULL) && (_stricmp(CacheLine->Key, Key) == 0))
1152 {
1153
1154 if (ContextIn != ContextOut)
1155 {
1156 ContextOut->Inf = ContextIn->Inf;
1157 ContextOut->Section = ContextIn->Section;
1158 }
1159 ContextOut->Line = (PVOID)CacheLine;
1160
1161 return TRUE;
1162 }
1163
1164 CacheLine = CacheLine->Next;
1165 }
1166
1167 return FALSE;
1168}
1169
1170
1171BOOLEAN
1173 PINFCONTEXT ContextIn,
1174 PCSTR Key,
1175 PINFCONTEXT ContextOut)
1176{
1177 PINFCACHELINE CacheLine;
1178
1179 if ((ContextIn == NULL) || (ContextOut == NULL) || (Key == NULL) || (*Key == 0))
1180 return FALSE;
1181
1182 if ((ContextIn->Inf == NULL) || (ContextIn->Section == NULL) || (ContextIn->Line == NULL))
1183 return FALSE;
1184
1185 CacheLine = (PINFCACHELINE)ContextIn->Line;
1186 while (CacheLine != NULL)
1187 {
1188 if ((CacheLine->Key != NULL) && (_stricmp(CacheLine->Key, Key) == 0))
1189 {
1190
1191 if (ContextIn != ContextOut)
1192 {
1193 ContextOut->Inf = ContextIn->Inf;
1194 ContextOut->Section = ContextIn->Section;
1195 }
1196 ContextOut->Line = (PVOID)CacheLine;
1197
1198 return TRUE;
1199 }
1200
1201 CacheLine = CacheLine->Next;
1202 }
1203
1204 return FALSE;
1205}
1206
1207
1208LONG
1210 HINF InfHandle,
1211 PCSTR Section)
1212{
1214 PINFCACHESECTION CacheSection;
1215
1216 if ((InfHandle == NULL) || (Section == NULL))
1217 {
1218// DPRINT("Invalid parameter\n");
1219 return -1;
1220 }
1221
1222 Cache = (PINFCACHE)InfHandle;
1223
1224 /* Iterate through list of sections */
1225 CacheSection = Cache->FirstSection;
1226 while (CacheSection != NULL)
1227 {
1228// DPRINT("Comparing '%s' and '%s'\n", CacheSection->Name, Section);
1229
1230 /* Are the section names the same? */
1231 if (_stricmp(CacheSection->Name, Section) == 0)
1232 {
1233 return CacheSection->LineCount;
1234 }
1235
1236 /* Get the next section */
1237 CacheSection = CacheSection->Next;
1238 }
1239
1240// DPRINT("Section not found\n");
1241
1242 return -1;
1243}
1244
1245
1246/* InfGetLineText */
1247
1248
1249LONG
1251{
1252 if ((Context == NULL) || (Context->Line == NULL))
1253 return 0;
1254
1255 return ((PINFCACHELINE)Context->Line)->FieldCount;
1256}
1257
1258
1259BOOLEAN
1263 PUCHAR ReturnBuffer,
1266{
1267 PINFCACHELINE CacheLine;
1268 PINFCACHEFIELD CacheField;
1269 ULONG Index;
1270 ULONG Size;
1271 PUCHAR Ptr;
1272
1273 if ((Context == NULL) || (Context->Line == NULL) || (FieldIndex == 0))
1274 {
1275// DPRINT("Invalid parameter\n");
1276 return FALSE;
1277 }
1278
1279 if (RequiredSize != NULL)
1280 *RequiredSize = 0;
1281
1282 CacheLine = (PINFCACHELINE)Context->Line;
1283
1284 if (FieldIndex > CacheLine->FieldCount)
1285 return FALSE;
1286
1287 CacheField = CacheLine->FirstField;
1288 for (Index = 1; Index < FieldIndex; Index++)
1289 CacheField = CacheField->Next;
1290
1291 Size = CacheLine->FieldCount - FieldIndex + 1;
1292
1293 if (RequiredSize != NULL)
1294 *RequiredSize = Size;
1295
1296 if (ReturnBuffer != NULL)
1297 {
1298 if (ReturnBufferSize < Size)
1299 return FALSE;
1300
1301 /* Copy binary data */
1302 Ptr = ReturnBuffer;
1303 while (CacheField != NULL)
1304 {
1305 *Ptr = (UCHAR)atoi(CacheField->Data); //strtoul(CacheField->Data, NULL, 16);
1306
1307 Ptr++;
1308 CacheField = CacheField->Next;
1309 }
1310 }
1311
1312 return TRUE;
1313}
1314
1315
1316BOOLEAN
1320 PLONG IntegerValue)
1321{
1322 PINFCACHELINE CacheLine;
1323 PINFCACHEFIELD CacheField;
1324 ULONG Index;
1325 PCHAR Ptr;
1326
1327 if ((Context == NULL) || (Context->Line == NULL) || (IntegerValue == NULL))
1328 {
1329// DPRINT("Invalid parameter\n");
1330 return FALSE;
1331 }
1332
1333 CacheLine = (PINFCACHELINE)Context->Line;
1334
1335 if (FieldIndex > CacheLine->FieldCount)
1336 {
1337// DPRINT("Invalid parameter\n");
1338 return FALSE;
1339 }
1340
1341 if (FieldIndex == 0)
1342 {
1343 Ptr = CacheLine->Key;
1344 }
1345 else
1346 {
1347 CacheField = CacheLine->FirstField;
1348 for (Index = 1; Index < FieldIndex; Index++)
1349 CacheField = CacheField->Next;
1350
1351 Ptr = CacheField->Data;
1352 }
1353
1354 *IntegerValue = atoi(Ptr); //strtol(Ptr, NULL, 0);
1355
1356 return TRUE;
1357}
1358
1359
1360BOOLEAN
1364 PCHAR ReturnBuffer,
1367{
1368 PINFCACHELINE CacheLine;
1369 PINFCACHEFIELD CacheField;
1370 PINFCACHEFIELD FieldPtr;
1371 ULONG Index;
1372 SIZE_T Size;
1373 PCHAR Ptr;
1374
1375 if ((Context == NULL) || (Context->Line == NULL) || (FieldIndex == 0))
1376 {
1377// DPRINT("Invalid parameter\n");
1378 return FALSE;
1379 }
1380
1381 if (RequiredSize != NULL)
1382 *RequiredSize = 0;
1383
1384 CacheLine = (PINFCACHELINE)Context->Line;
1385
1386 if (FieldIndex > CacheLine->FieldCount)
1387 return FALSE;
1388
1389 CacheField = CacheLine->FirstField;
1390 for (Index = 1; Index < FieldIndex; Index++)
1391 CacheField = CacheField->Next;
1392
1393 /* Calculate the required buffer size */
1394 FieldPtr = CacheField;
1395 Size = 0;
1396 while (FieldPtr != NULL)
1397 {
1398 Size += (strlen(FieldPtr->Data) + 1);
1399 FieldPtr = FieldPtr->Next;
1400 }
1401 Size++;
1402
1403 if (RequiredSize != NULL)
1405
1406 if (ReturnBuffer != NULL)
1407 {
1408 if (ReturnBufferSize < Size)
1409 return FALSE;
1410
1411 /* Copy multi-sz string */
1412 Ptr = ReturnBuffer;
1413 FieldPtr = CacheField;
1414 while (FieldPtr != NULL)
1415 {
1416 Size = strlen(FieldPtr->Data) + 1;
1417
1418 strcpy(Ptr, FieldPtr->Data);
1419
1420 Ptr = Ptr + Size;
1421 FieldPtr = FieldPtr->Next;
1422 }
1423 *Ptr = 0;
1424 }
1425
1426 return TRUE;
1427}
1428
1429
1430BOOLEAN
1434 PCHAR ReturnBuffer,
1437{
1438 PINFCACHELINE CacheLine;
1439 PINFCACHEFIELD CacheField;
1440 ULONG Index;
1441 PCHAR Ptr;
1442 SIZE_T Size;
1443
1444 if ((Context == NULL) || (Context->Line == NULL))
1445 {
1446// DPRINT("Invalid parameter\n");
1447 return FALSE;
1448 }
1449
1450 if (RequiredSize != NULL)
1451 *RequiredSize = 0;
1452
1453 CacheLine = (PINFCACHELINE)Context->Line;
1454
1455 if (FieldIndex > CacheLine->FieldCount)
1456 return FALSE;
1457
1458 if (FieldIndex == 0)
1459 {
1460 Ptr = CacheLine->Key;
1461 }
1462 else
1463 {
1464 CacheField = CacheLine->FirstField;
1465 for (Index = 1; Index < FieldIndex; Index++)
1466 CacheField = CacheField->Next;
1467
1468 Ptr = CacheField->Data;
1469 }
1470
1471 Size = strlen(Ptr) + 1;
1472
1473 if (RequiredSize != NULL)
1475
1476 if (ReturnBuffer != NULL)
1477 {
1478 if (ReturnBufferSize < Size)
1479 return FALSE;
1480
1481 strcpy(ReturnBuffer, Ptr);
1482 }
1483
1484 return TRUE;
1485}
1486
1487
1488
1489
1490BOOLEAN
1493 PCSTR *Key,
1494 PCSTR *Data)
1495{
1496 PINFCACHELINE CacheKey;
1497
1498 if ((Context == NULL) || (Context->Line == NULL) || (Data == NULL))
1499 {
1500// DPRINT("Invalid parameter\n");
1501 return FALSE;
1502 }
1503
1504 CacheKey = (PINFCACHELINE)Context->Line;
1505 if (Key != NULL)
1506 *Key = CacheKey->Key;
1507
1508 *Data = (CacheKey->FirstField == NULL) ? NULL : CacheKey->FirstField->Data;
1509
1510 return TRUE;
1511}
1512
1513
1514BOOLEAN
1518 PCSTR *Data)
1519{
1520 PINFCACHELINE CacheLine;
1521 PINFCACHEFIELD CacheField;
1522 ULONG Index;
1523
1524 if ((Context == NULL) || (Context->Line == NULL) || (Data == NULL))
1525 {
1526// DPRINT("Invalid parameter\n");
1527 return FALSE;
1528 }
1529
1530 CacheLine = (PINFCACHELINE)Context->Line;
1531
1532 if (FieldIndex > CacheLine->FieldCount)
1533 return FALSE;
1534
1535 if (FieldIndex == 0)
1536 {
1537 *Data = CacheLine->Key;
1538 }
1539 else
1540 {
1541 CacheField = CacheLine->FirstField;
1542 for (Index = 1; Index < FieldIndex; Index++)
1543 CacheField = CacheField->Next;
1544
1545 *Data = CacheField->Data;
1546 }
1547
1548 return TRUE;
1549}
1550
1551
1552/* EOF */
unsigned char BOOLEAN
#define isspace(c)
Definition: acclib.h:69
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static int state
Definition: maze.c:121
parser_state
Definition: import.c:59
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:220
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:252
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
FORCEINLINE PVOID FrLdrTempAlloc(_In_ SIZE_T Size, _In_ ULONG Tag)
Definition: mm.h:188
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
#define STATUS_WRONG_INF_STYLE
Definition: inffile.h:13
PULONG * PHINF
Definition: inffile.h:18
#define STATUS_BAD_SECTION_NAME_LINE
Definition: inffile.h:11
#define _stricmp
Definition: cat.c:22
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
Definition: _stack.h:55
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Success
Definition: eventcreate.c:712
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
GLuint GLuint end
Definition: gl.h:1545
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define MAX_FIELD_LEN
Definition: infcore.c:18
parser_state
Definition: infcore.c:26
BOOLEAN InfFindFirstLine(HINF InfHandle, PCSTR Section, PCSTR Key, PINFCONTEXT Context)
Definition: inffile.c:1050
static PINFCACHELINE InfpCacheFreeLine(PINFCACHELINE Line)
Definition: inffile.c:135
#define MAX_FIELD_LEN
Definition: inffile.c:16
const CHAR *(* parser_state_func)(struct parser *parser, const CHAR *pos)
Definition: inffile.c:102
static struct field * add_field_from_token(struct parser *parser, int is_key)
Definition: inffile.c:490
static __inline int is_eol(struct parser *parser, const CHAR *ptr)
Definition: inffile.c:422
LONG InfGetLineCount(HINF InfHandle, PCSTR Section)
Definition: inffile.c:1209
struct _INFCACHEFIELD * PINFCACHEFIELD
static __inline enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: inffile.c:406
struct _INFCACHESECTION * PINFCACHESECTION
static int push_token(struct parser *parser, const CHAR *pos)
Definition: inffile.c:434
BOOLEAN InfGetData(PINFCONTEXT Context, PCSTR *Key, PCSTR *Data)
Definition: inffile.c:1491
struct _INFCACHELINE INFCACHELINE
static BOOLEAN InfpParseBuffer(PINFCACHE file, PCCHAR buffer, PCCHAR end, PULONG error_line)
Definition: inffile.c:878
struct _INFCACHESECTION INFCACHESECTION
#define TAG_INF_CACHE
Definition: inffile.c:24
BOOLEAN InfGetIntField(PINFCONTEXT Context, ULONG FieldIndex, PLONG IntegerValue)
Definition: inffile.c:1317
static const CHAR * value_name_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:676
#define TAG_INF_LINE
Definition: inffile.c:22
#define TAG_INF_FIELD
Definition: inffile.c:21
static PVOID InfpAddFieldToLine(PINFCACHELINE Line, PCSTR Data)
Definition: inffile.c:331
static const CHAR * comment_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:862
#define TAG_INF_SECTION
Definition: inffile.c:23
static PVOID add_section_from_token(struct parser *parser)
Definition: inffile.c:458
BOOLEAN InfFindNextMatchLine(PINFCONTEXT ContextIn, PCSTR Key, PINFCONTEXT ContextOut)
Definition: inffile.c:1172
static PINFCACHESECTION InfpCacheFindSection(PINFCACHE Cache, PCSTR Name)
Definition: inffile.c:196
#define CONTROL_Z
Definition: inffile.c:14
BOOLEAN InfGetStringField(PINFCONTEXT Context, ULONG FieldIndex, PCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: inffile.c:1431
static PINFCACHELINE InfpCacheAddLine(PINFCACHESECTION Section)
Definition: inffile.c:271
static const CHAR * line_start_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:546
static const CHAR * key_name_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:618
static const CHAR * quotes_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:778
static PINFCACHELINE InfpCacheFindKeyLine(PINFCACHESECTION Section, PCSTR Key)
Definition: inffile.c:368
static __inline void push_state(struct parser *parser, enum parser_state state)
Definition: inffile.c:390
VOID InfCloseFile(HINF InfHandle)
Definition: inffile.c:1028
BOOLEAN InfGetMultiSzField(PINFCONTEXT Context, ULONG FieldIndex, PCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: inffile.c:1361
BOOLEAN InfGetDataField(PINFCONTEXT Context, ULONG FieldIndex, PCSTR *Data)
Definition: inffile.c:1515
@ NB_PARSER_STATES
Definition: inffile.c:82
@ SECTION_NAME
Definition: inffile.c:74
@ TRAILING_SPACES
Definition: inffile.c:80
@ QUOTES
Definition: inffile.c:78
@ LINE_START
Definition: inffile.c:73
@ EOL_BACKSLASH
Definition: inffile.c:77
@ COMMENT
Definition: inffile.c:81
@ LEADING_SPACES
Definition: inffile.c:79
@ KEY_NAME
Definition: inffile.c:75
@ VALUE_NAME
Definition: inffile.c:76
static const CHAR * trailing_spaces_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:838
static __inline void pop_state(struct parser *parser)
Definition: inffile.c:398
BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn, PINFCONTEXT ContextOut)
Definition: inffile.c:1107
BOOLEAN InfFindFirstMatchLine(PINFCONTEXT ContextIn, PCSTR Key, PINFCONTEXT ContextOut)
Definition: inffile.c:1135
static PVOID InfpAddKeyToLine(PINFCACHELINE Line, PCSTR Key)
Definition: inffile.c:309
static __inline int is_eof(struct parser *parser, const CHAR *ptr)
Definition: inffile.c:415
BOOLEAN InfGetBinaryField(PINFCONTEXT Context, ULONG FieldIndex, PUCHAR ReturnBuffer, ULONG ReturnBufferSize, PULONG RequiredSize)
Definition: inffile.c:1260
static const CHAR * section_name_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:592
static PINFCACHESECTION InfpCacheAddSection(PINFCACHE Cache, PCSTR Name)
Definition: inffile.c:226
LONG InfGetFieldCount(PINFCONTEXT Context)
Definition: inffile.c:1250
struct _INFCACHELINE * PINFCACHELINE
BOOLEAN InfOpenFile(PHINF InfHandle, PCSTR FileName, PULONG ErrorLine)
Definition: inffile.c:918
static PINFCACHESECTION InfpCacheFreeSection(PINFCACHESECTION Section)
Definition: inffile.c:170
#define TAG_INF_KEY
Definition: inffile.c:20
#define MAX_SECTION_NAME_LEN
Definition: inffile.c:15
struct _INFCACHE * PINFCACHE
struct _INFCACHEFIELD INFCACHEFIELD
struct _INFCACHE INFCACHE
static VOID close_current_line(struct parser *parser)
Definition: inffile.c:537
static const CHAR * leading_spaces_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:812
#define TAG_INF_FILE
Definition: inffile.c:25
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: inffile.c:117
static const CHAR * eol_backslash_state(struct parser *parser, const CHAR *pos)
Definition: inffile.c:733
PVOID HINF
Definition: infsupp.h:21
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static PVOID ptr
Definition: dispmode.c:27
int Count
Definition: noreturn.cpp:7
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ OpenReadOnly
Definition: arc.h:65
#define memset(x, y, z)
Definition: compat.h:39
_In_ DWORD FieldIndex
Definition: setupapi.h:1895
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1897
Definition: fatfs.h:173
Definition: ncftp.h:79
struct _INFCACHEFIELD * Next
Definition: inffile.c:29
struct _INFCACHEFIELD * Prev
Definition: inffile.c:30
CHAR Data[1]
Definition: inffile.c:32
PINFCACHEFIELD FirstField
Definition: inffile.c:44
PINFCACHEFIELD LastField
Definition: inffile.c:45
ULONG FieldCount
Definition: inffile.c:40
struct _INFCACHELINE * Prev
Definition: inffile.c:38
PCHAR Key
Definition: inffile.c:42
struct _INFCACHELINE * Next
Definition: inffile.c:37
PINFCACHELINE LastLine
Definition: inffile.c:55
struct _INFCACHESECTION * Prev
Definition: inffile.c:52
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
PINFCACHESECTION FirstSection
Definition: inffile.c:64
PINFCACHESECTION LastSection
Definition: inffile.c:65
PINFCACHESECTION StringsSection
Definition: inffile.c:67
HINF Inf
Definition: infsupp.h:24
UINT Line
Definition: infsupp.h:27
UINT Section
Definition: infsupp.h:26
Definition: parser.c:44
Definition: fci.c:127
Definition: import.c:81
unsigned int line_pos
Definition: inffile.c:96
PINFCACHESECTION cur_section
Definition: inffile.c:94
int stack_pos
Definition: inffile.c:92
const CHAR * end
Definition: inffile.c:88
enum parser_state state
Definition: import.c:95
CHAR token[MAX_FIELD_LEN+1]
Definition: inffile.c:99
unsigned int token_len
Definition: inffile.c:98
const CHAR * start
Definition: inffile.c:87
enum parser_state stack[4]
Definition: inffile.c:91
unsigned int error
Definition: inffile.c:97
PINFCACHE file
Definition: inffile.c:89
PINFCACHELINE line
Definition: inffile.c:95
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
ULONG LowPart
Definition: typedefs.h:106
int ret
_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
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175