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