ReactOS 0.4.16-dev-976-g18fc5a1
parser.c
Go to the documentation of this file.
1/*
2 * INF file parsing
3 *
4 * Copyright 2002 Alexandre Julliard for CodeWeavers
5 * 2005-2006 Herv� Poussineau (hpoussin@reactos.org)
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22/* Partially synced with Wine Staging 2.2 */
23
24#include "setupapi_private.h"
25
26#include <ndk/obfuncs.h>
27
28/* Unicode constants */
29static const WCHAR BackSlash[] = {'\\',0};
30static const WCHAR Class[] = {'C','l','a','s','s',0};
31static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0};
32static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
33static const WCHAR InfFileSpecification[] = {'*','.','i','n','f',0};
34
35#define CONTROL_Z '\x1a'
36#define MAX_SECTION_NAME_LEN 255
37#define MAX_FIELD_LEN 511 /* larger fields get silently truncated */
38/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */
39#define MAX_STRING_LEN (MAX_INF_STRING_LENGTH+1)
40
41/* inf file structure definitions */
42
43struct field
44{
45 const WCHAR *text; /* field text */
46};
47
48struct line
49{
50 int first_field; /* index of first field in field array */
51 int nb_fields; /* number of fields in line */
52 int key_field; /* index of field for key or -1 if no key */
53};
54
55struct section
56{
57 const WCHAR *name; /* section name */
58 unsigned int nb_lines; /* number of used lines */
59 unsigned int alloc_lines; /* total number of allocated lines in array below */
60 struct line lines[16]; /* lines information (grown dynamically, 16 is initial size) */
61};
62
63struct inf_file
64{
65 struct inf_file *next; /* next appended file */
66 WCHAR *strings; /* buffer for string data (section names and field values) */
67 WCHAR *string_pos; /* position of next available string in buffer */
68 unsigned int nb_sections; /* number of used sections */
69 unsigned int alloc_sections; /* total number of allocated section pointers */
70 struct section **sections; /* section pointers array */
71 unsigned int nb_fields;
72 unsigned int alloc_fields;
73 struct field *fields;
74 int strings_section; /* index of [Strings] section or -1 if none */
75 WCHAR *filename; /* filename of the INF */
76};
77
78/* parser definitions */
79
81{
82 LINE_START, /* at beginning of a line */
83 SECTION_NAME, /* parsing a section name */
84 KEY_NAME, /* parsing a key name */
85 VALUE_NAME, /* parsing a value name */
86 EOL_BACKSLASH, /* backslash at end of line */
87 QUOTES, /* inside quotes */
88 LEADING_SPACES, /* leading spaces */
89 TRAILING_SPACES, /* trailing spaces */
90 COMMENT, /* inside a comment */
92};
93
94struct parser
95{
96 const WCHAR *start; /* start position of item being parsed */
97 const WCHAR *end; /* end of buffer */
98 struct inf_file *file; /* file being built */
99 enum parser_state state; /* current parser state */
100 enum parser_state stack[4]; /* state stack */
101 int stack_pos; /* current pos in stack */
102
103 int cur_section; /* index of section being parsed*/
104 struct line *line; /* current line */
105 unsigned int line_pos; /* current line position in file */
106 unsigned int broken_line; /* first line containing invalid data (if any) */
107 unsigned int error; /* error code */
108 unsigned int token_len; /* current token len */
109 WCHAR token[MAX_FIELD_LEN+1]; /* current token */
110};
111
112typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );
113
114/* parser state machine functions */
115static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );
116static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );
117static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );
118static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );
119static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );
120static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );
121static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );
122static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );
123static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos );
124
126{
127 line_start_state, /* LINE_START */
128 section_name_state, /* SECTION_NAME */
129 key_name_state, /* KEY_NAME */
130 value_name_state, /* VALUE_NAME */
131 eol_backslash_state, /* EOL_BACKSLASH */
132 quotes_state, /* QUOTES */
133 leading_spaces_state, /* LEADING_SPACES */
134 trailing_spaces_state, /* TRAILING_SPACES */
135 comment_state /* COMMENT */
136};
137
138
139/* Unicode string constants */
140static const WCHAR Version[] = {'V','e','r','s','i','o','n',0};
141static const WCHAR Signature[] = {'S','i','g','n','a','t','u','r','e',0};
142static const WCHAR Chicago[] = {'$','C','h','i','c','a','g','o','$',0};
143static const WCHAR WindowsNT[] = {'$','W','i','n','d','o','w','s',' ','N','T','$',0};
144static const WCHAR Windows95[] = {'$','W','i','n','d','o','w','s',' ','9','5','$',0};
145static const WCHAR LayoutFile[] = {'L','a','y','o','u','t','F','i','l','e',0};
146
147/* extend an array, allocating more memory if necessary */
148static void *grow_array( void *array, unsigned int *count, size_t elem )
149{
150 void *new_array;
151 unsigned int new_count = *count + *count / 2;
152 if (new_count < 32) new_count = 32;
153
154 if (array)
155 new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );
156 else
157 new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );
158
159 if (new_array)
160 *count = new_count;
161 else
163 return new_array;
164}
165
166
167/* get the directory of the inf file (as counted string, not null-terminated) */
168static const WCHAR *get_inf_dir( const struct inf_file *file, unsigned int *len )
169{
170 const WCHAR *p = strrchrW( file->filename, '\\' );
171 *len = p ? (p + 1 - file->filename) : 0;
172 return file->filename;
173}
174
175
176/* find a section by name */
177static int find_section( const struct inf_file *file, const WCHAR *name )
178{
179 unsigned int i;
180
181 for (i = 0; i < file->nb_sections; i++)
182 if (!strcmpiW( name, file->sections[i]->name )) return i;
183 return -1;
184}
185
186
187/* find a line by name */
188static struct line *find_line( struct inf_file *file, int section_index, const WCHAR *name )
189{
190 struct section *section;
191 struct line *line;
192 unsigned int i;
193
194 if (section_index < 0 || section_index >= file->nb_sections) return NULL;
195 section = file->sections[section_index];
196 for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
197 {
198 if (line->key_field == -1) continue;
199 if (!strcmpiW( name, file->fields[line->key_field].text )) return line;
200 }
201 return NULL;
202}
203
204
205/* add a section to the file and return the section index */
206static int add_section( struct inf_file *file, const WCHAR *name )
207{
208 struct section *section;
209
210 if (file->nb_sections >= file->alloc_sections)
211 {
212 if (!(file->sections = grow_array( file->sections, &file->alloc_sections,
213 sizeof(file->sections[0]) ))) return -1;
214 }
215 if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) ))) return -1;
216 section->name = name;
217 section->nb_lines = 0;
218 section->alloc_lines = sizeof(section->lines)/sizeof(section->lines[0]);
219 file->sections[file->nb_sections] = section;
220 return file->nb_sections++;
221}
222
223
224/* add a line to a given section */
225static struct line *add_line( struct inf_file *file, int section_index )
226{
227 struct section *section;
228 struct line *line;
229
230 ASSERT( section_index >= 0 && section_index < file->nb_sections );
231
232 section = file->sections[section_index];
233 if (section->nb_lines == section->alloc_lines) /* need to grow the section */
234 {
235 int size = sizeof(*section) - sizeof(section->lines) + 2*section->alloc_lines*sizeof(*line);
236 if (!(section = HeapReAlloc( GetProcessHeap(), 0, section, size ))) return NULL;
237 section->alloc_lines *= 2;
238 file->sections[section_index] = section;
239 }
241 line->first_field = file->nb_fields;
242 line->nb_fields = 0;
243 line->key_field = -1;
244 return line;
245}
246
247
248/* retrieve a given line from section/line index */
249static inline struct line *get_line( struct inf_file *file, unsigned int section_index,
250 unsigned int line_index )
251{
252 struct section *section;
253
254 if (section_index >= file->nb_sections) return NULL;
255 section = file->sections[section_index];
256 if (line_index >= section->nb_lines) return NULL;
257 return &section->lines[line_index];
258}
259
260
261/* retrieve a given field from section/line/field index */
262static struct field *get_field( struct inf_file *file, int section_index, int line_index,
263 int field_index )
264{
265 struct line *line = get_line( file, section_index, line_index );
266
267 if (!line) return NULL;
268 if (!field_index) /* get the key */
269 {
270 if (line->key_field == -1) return NULL;
271 return &file->fields[line->key_field];
272 }
273 field_index--;
274 if (field_index >= line->nb_fields) return NULL;
275 return &file->fields[line->first_field + field_index];
276}
277
278
279/* allocate a new field, growing the array if necessary */
280static struct field *add_field( struct inf_file *file, const WCHAR *text )
281{
282 struct field *field;
283
284 if (file->nb_fields >= file->alloc_fields)
285 {
286 if (!(file->fields = grow_array( file->fields, &file->alloc_fields,
287 sizeof(file->fields[0]) ))) return NULL;
288 }
289 field = &file->fields[file->nb_fields++];
290 field->text = text;
291 return field;
292}
293
294
295/* retrieve the string substitution for a directory id */
296static const WCHAR *get_dirid_subst( const struct inf_file *file, int dirid, unsigned int *len )
297{
298 const WCHAR *ret;
299
300 if (dirid == DIRID_SRCPATH) return get_inf_dir( file, len );
301 ret = DIRID_get_string( dirid );
302 if (ret) *len = strlenW(ret);
303 return ret;
304}
305
306
307/* retrieve the string substitution for a given string, or NULL if not found */
308/* if found, len is set to the substitution length */
309static const WCHAR *get_string_subst( const struct inf_file *file, const WCHAR *str, unsigned int *len,
310 BOOL no_trailing_slash )
311{
312 static const WCHAR percent = '%';
313
314 struct section *strings_section;
315 struct line *line;
316 struct field *field;
317 unsigned int i, j;
318 int dirid;
319 WCHAR *dirid_str, *end;
320 const WCHAR *ret = NULL;
321 WCHAR StringLangId[13] = {'S','t','r','i','n','g','s','.',0};
322 TCHAR Lang[5];
323
324 if (!*len) /* empty string (%%) is replaced by single percent */
325 {
326 *len = 1;
327 return &percent;
328 }
329 if (file->strings_section == -1) goto not_found;
330 strings_section = file->sections[file->strings_section];
331 for (j = 0, line = strings_section->lines; j < strings_section->nb_lines; j++, line++)
332 {
333 if (line->key_field == -1) continue;
334 if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue;
335 if (!file->fields[line->key_field].text[*len]) break;
336 }
337 if (j == strings_section->nb_lines || !line->nb_fields) goto not_found;
338 field = &file->fields[line->first_field];
339 GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, Lang, sizeof(Lang)/sizeof(TCHAR)); // get the current system locale for translated strings
340
341 strcpyW(StringLangId + 8, Lang + 2);
342 // now you have e.g. Strings.07 for german neutral translations
343 for (i = 0; i < file->nb_sections; i++) // search in all sections
344 {
345 if (!strcmpiW(file->sections[i]->name,StringLangId)) // if the section is a Strings.* section
346 {
347 strings_section = file->sections[i]; // select this section for further use
348 for (j = 0, line = strings_section->lines; j < strings_section->nb_lines; j++, line++) // process all lines in this section
349 {
350 if (line->key_field == -1) continue; // if no key then skip
351 if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue; // if wrong key name, then skip
352 if (!file->fields[line->key_field].text[*len]) // if value exist
353 {
354 field = &file->fields[line->first_field]; // then extract value and
355 break; // no more search necessary
356 }
357 }
358 }
359 }
360
361 strcpyW(StringLangId + 8, Lang); // append the Language identifier from GetLocaleInfo
362 // now you have e.g. Strings.0407 for german translations
363 for (i = 0; i < file->nb_sections; i++) // search in all sections
364 {
365 if (!strcmpiW(file->sections[i]->name,StringLangId)) // if the section is a Strings.* section
366 {
367 strings_section = file->sections[i]; // select this section for further use
368 for (j = 0, line = strings_section->lines; j < strings_section->nb_lines; j++, line++) // process all lines in this section
369 {
370 if (line->key_field == -1) continue; // if no key then skip
371 if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue; // if wrong key name, then skip
372 if (!file->fields[line->key_field].text[*len]) // if value exist
373 {
374 field = &file->fields[line->first_field]; // then extract value and
375 break; // no more search necessary
376 }
377 }
378 }
379 }
380 *len = strlenW( field->text ); // set length
381 ret = field->text; // return the english or translated string
382 return ret;
383
384
385 not_found: /* check for integer id */
386 if ((dirid_str = HeapAlloc( GetProcessHeap(), 0, (*len+1) * sizeof(WCHAR) )))
387 {
388 memcpy( dirid_str, str, *len * sizeof(WCHAR) );
389 dirid_str[*len] = 0;
390 dirid = strtolW( dirid_str, &end, 10 );
391 if (!*end) ret = get_dirid_subst( file, dirid, len );
392 if (no_trailing_slash && ret && *len && ret[*len - 1] == '\\') *len -= 1;
393 HeapFree( GetProcessHeap(), 0, dirid_str );
394 return ret;
395 }
396 return NULL;
397}
398
399
400/* do string substitutions on the specified text */
401/* the buffer is assumed to be large enough */
402/* returns necessary length not including terminating null */
403static unsigned int PARSER_string_substW( const struct inf_file *file, const WCHAR *text,
404 WCHAR *buffer, unsigned int size )
405{
406 const WCHAR *start, *subst, *p;
407 unsigned int len, total = 0;
408 BOOL inside = FALSE;
409
410 if (!buffer) size = MAX_STRING_LEN + 1;
411 for (p = start = text; *p; p++)
412 {
413 if (*p != '%') continue;
414 inside = !inside;
415 if (inside) /* start of a %xx% string */
416 {
417 len = p - start;
418 if (len > size - 1) len = size - 1;
419 if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
420 total += len;
421 size -= len;
422 start = p;
423 }
424 else /* end of the %xx% string, find substitution */
425 {
426 len = p - start - 1;
427 subst = get_string_subst( file, start + 1, &len, p[1] == '\\' );
428 if (!subst)
429 {
430 subst = start;
431 len = p - start + 1;
432 }
433 if (len > size - 1) len = size - 1;
434 if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );
435 total += len;
436 size -= len;
437 start = p + 1;
438 }
439 }
440
441 if (start != p) /* unfinished string, copy it */
442 {
443 len = p - start;
444 if (len > size - 1) len = size - 1;
445 if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
446 total += len;
447 }
448 if (buffer && size) buffer[total] = 0;
449 return total;
450}
451
452
453/* do string substitutions on the specified text */
454/* the buffer is assumed to be large enough */
455/* returns necessary length not including terminating null */
456static unsigned int PARSER_string_substA( const struct inf_file *file, const WCHAR *text,
457 char *buffer, unsigned int size )
458{
459 WCHAR buffW[MAX_STRING_LEN+1];
460 DWORD ret;
461
462 unsigned int len = PARSER_string_substW( file, text, buffW, sizeof(buffW)/sizeof(WCHAR) );
463 if (!buffer) RtlUnicodeToMultiByteSize( &ret, buffW, len * sizeof(WCHAR) );
464 else
465 {
466 RtlUnicodeToMultiByteN( buffer, size-1, &ret, buffW, len * sizeof(WCHAR) );
467 buffer[ret] = 0;
468 }
469 return ret;
470}
471
472
473/* push some string data into the strings buffer */
474static WCHAR *push_string( struct inf_file *file, const WCHAR *string )
475{
476 WCHAR *ret = file->string_pos;
477 strcpyW( ret, string );
478 file->string_pos += strlenW( ret ) + 1;
479 return ret;
480}
481
482
483/* push the current state on the parser stack */
484static inline void push_state( struct parser *parser, enum parser_state state )
485{
486 ASSERT( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) );
488}
489
490
491/* pop the current state */
492static inline void pop_state( struct parser *parser )
493{
496}
497
498
499/* set the parser state and return the previous one */
500static inline enum parser_state set_state( struct parser *parser, enum parser_state state )
501{
503 parser->state = state;
504 return ret;
505}
506
507
508/* check if the pointer points to an end of file */
509static inline BOOL is_eof( const struct parser *parser, const WCHAR *ptr )
510{
511 return (ptr >= parser->end || *ptr == CONTROL_Z);
512}
513
514
515/* check if the pointer points to an end of line */
516static inline BOOL is_eol( const struct parser *parser, const WCHAR *ptr )
517{
518 return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\n');
519}
520
521
522/* push data from current token start up to pos into the current token */
523static int push_token( struct parser *parser, const WCHAR *pos )
524{
525 int len = pos - parser->start;
526 const WCHAR *src = parser->start;
528
530
531 parser->token_len += len;
532 for ( ; len > 0; len--, dst++, src++) *dst = *src ? *src : ' ';
533 *dst = 0;
534 parser->start = pos;
535 return 0;
536}
537
538
539/* add a section with the current token as name */
541{
542 int section_index;
543
545 {
547 return -1;
548 }
549 if ((section_index = find_section( parser->file, parser->token )) == -1)
550 {
551 /* need to create a new one */
553 if ((section_index = add_section( parser->file, name )) == -1)
554 {
556 return -1;
557 }
558 }
559 parser->token_len = 0;
560 parser->cur_section = section_index;
561 return section_index;
562}
563
564
565/* add a field containing the current token to the current line */
566static struct field *add_field_from_token( struct parser *parser, BOOL is_key )
567{
568 struct field *field;
569 WCHAR *text;
570
571 if (!parser->line) /* need to start a new line */
572 {
573 if (parser->cur_section == -1) /* got a line before the first section */
574 {
576 return NULL;
577 }
578 if (!(parser->line = add_line( parser->file, parser->cur_section ))) goto error;
579 }
580 else ASSERT(!is_key);
581
583 if ((field = add_field( parser->file, text )))
584 {
585 if (!is_key) parser->line->nb_fields++;
586 else
587 {
588 /* replace first field by key field */
589 parser->line->key_field = parser->line->first_field;
590 parser->line->first_field++;
591 }
592 parser->token_len = 0;
593 return field;
594 }
595 error:
597 return NULL;
598}
599
600
601/* close the current line and prepare for parsing a new one */
602static void close_current_line( struct parser *parser )
603{
604 struct line *cur_line = parser->line;
605
606 if (cur_line)
607 {
608 /* if line has a single field and no key, the field is the key too */
609 if (cur_line->nb_fields == 1 && cur_line->key_field == -1)
610 cur_line->key_field = cur_line->first_field;
611 }
612 parser->line = NULL;
613}
614
615
616/* handler for parser LINE_START state */
617static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
618{
619 const WCHAR *p;
620
621 for (p = pos; !is_eof( parser, p ); p++)
622 {
623 switch(*p)
624 {
625 case '\n':
626 parser->line_pos++;
628 break;
629 case ';':
632 return p + 1;
633 case '[':
634 parser->start = p + 1;
636 return p + 1;
637 default:
638 if (isspaceW(*p)) break;
639 if (parser->cur_section != -1)
640 {
641 parser->start = p;
643 return p;
644 }
645 if (!parser->broken_line)
647 break;
648 }
649 }
651 return NULL;
652}
653
654
655/* handler for parser SECTION_NAME state */
656static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )
657{
658 const WCHAR *p;
659
660 for (p = pos; !is_eol( parser, p ); p++)
661 {
662 if (*p == ']')
663 {
664 push_token( parser, p );
665 if (add_section_from_token( parser ) == -1) return NULL;
667 set_state( parser, COMMENT ); /* ignore everything else on the line */
668 return p + 1;
669 }
670 }
671 parser->error = ERROR_BAD_SECTION_NAME_LINE; /* unfinished section name */
672 return NULL;
673}
674
675
676/* handler for parser KEY_NAME state */
677static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
678{
679 const WCHAR *p, *token_end = parser->start;
680
681 for (p = pos; !is_eol( parser, p ); p++)
682 {
683 if (*p == ',') break;
684 switch(*p)
685 {
686
687 case '=':
688 push_token( parser, token_end );
689 if (!add_field_from_token( parser, TRUE )) return NULL;
690 parser->start = p + 1;
693 return p + 1;
694 case ';':
695 push_token( parser, token_end );
696 if (!add_field_from_token( parser, FALSE )) return NULL;
699 return p + 1;
700 case '"':
701 push_token( parser, p );
702 parser->start = p + 1;
705 return p + 1;
706 case '\\':
707 push_token( parser, token_end );
708 parser->start = p;
711 return p;
712 default:
713 if (!isspaceW(*p)) token_end = p + 1;
714 else
715 {
716 push_token( parser, p );
719 return p;
720 }
721 break;
722 }
723 }
724 push_token( parser, token_end );
726 return p;
727}
728
729
730/* handler for parser VALUE_NAME state */
731static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )
732{
733 const WCHAR *p, *token_end = parser->start;
734
735 for (p = pos; !is_eol( parser, p ); p++)
736 {
737 switch(*p)
738 {
739 case ';':
740 push_token( parser, token_end );
741 if (!add_field_from_token( parser, FALSE )) return NULL;
744 return p + 1;
745 case ',':
746 push_token( parser, token_end );
747 if (!add_field_from_token( parser, FALSE )) return NULL;
748 parser->start = p + 1;
751 return p + 1;
752 case '"':
753 push_token( parser, p );
754 parser->start = p + 1;
757 return p + 1;
758 case '\\':
759 push_token( parser, token_end );
760 parser->start = p;
763 return p;
764 default:
765 if (!isspaceW(*p)) token_end = p + 1;
766 else
767 {
768 push_token( parser, p );
771 return p;
772 }
773 break;
774 }
775 }
776 push_token( parser, token_end );
777 if (!add_field_from_token( parser, FALSE )) return NULL;
779 return p;
780}
781
782
783/* handler for parser EOL_BACKSLASH state */
784static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
785{
786 const WCHAR *p;
787
788 for (p = pos; !is_eof( parser, p ); p++)
789 {
790 switch(*p)
791 {
792 case '\n':
793 parser->line_pos++;
794 parser->start = p + 1;
796 return p + 1;
797 case '\\':
798 continue;
799 case ';':
802 return p + 1;
803 default:
804 if (isspaceW(*p)) continue;
805 push_token( parser, p );
806 pop_state( parser );
807 return p;
808 }
809 }
810 parser->start = p;
811 pop_state( parser );
812 return p;
813}
814
815
816/* handler for parser QUOTES state */
817static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
818{
819 const WCHAR *p;
820
821 for (p = pos; !is_eol( parser, p ); p++)
822 {
823 if (*p == '"')
824 {
825 if (p+1 < parser->end && p[1] == '"') /* double quotes */
826 {
827 push_token( parser, p + 1 );
828 parser->start = p + 2;
829 p++;
830 }
831 else /* end of quotes */
832 {
833 push_token( parser, p );
834 parser->start = p + 1;
835 pop_state( parser );
836 return p + 1;
837 }
838 }
839 }
840 push_token( parser, p );
841 pop_state( parser );
842 return p;
843}
844
845
846/* handler for parser LEADING_SPACES state */
847static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )
848{
849 const WCHAR *p;
850
851 for (p = pos; !is_eol( parser, p ); p++)
852 {
853 if (*p == '\\')
854 {
855 parser->start = p;
857 return p;
858 }
859 if (!isspaceW(*p)) break;
860 }
861 parser->start = p;
862 pop_state( parser );
863 return p;
864}
865
866
867/* handler for parser TRAILING_SPACES state */
868static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
869{
870 const WCHAR *p;
871
872 for (p = pos; !is_eol( parser, p ); p++)
873 {
874 if (*p == '\\')
875 {
877 return p;
878 }
879 if (!isspaceW(*p)) break;
880 }
881 pop_state( parser );
882 return p;
883}
884
885
886/* handler for parser COMMENT state */
887static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )
888{
889 const WCHAR *p = pos;
890
891 while (!is_eol( parser, p )) p++;
892 pop_state( parser );
893 return p;
894}
895
896
897static void free_inf_file( struct inf_file *file )
898{
899 unsigned int i;
900
901 for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
902 HeapFree( GetProcessHeap(), 0, file->filename );
903 HeapFree( GetProcessHeap(), 0, file->sections );
904 HeapFree( GetProcessHeap(), 0, file->fields );
905 HeapFree( GetProcessHeap(), 0, file->strings );
907}
908
909
910/* parse a complete buffer */
911static DWORD parse_buffer( struct inf_file *file, const WCHAR *buffer, const WCHAR *end,
912 UINT *error_line )
913{
914 static const WCHAR Strings[] = {'S','t','r','i','n','g','s',0};
915
916 struct parser parser;
917 const WCHAR *pos = buffer;
918
920 parser.end = end;
921 parser.file = file;
922 parser.line = NULL;
924 parser.stack_pos = 0;
925 parser.cur_section = -1;
926 parser.line_pos = 1;
928 parser.error = 0;
929 parser.token_len = 0;
930
931 /* parser main loop */
932 while (pos) pos = (parser_funcs[parser.state])( &parser, pos );
933
934 /* trim excess buffer space */
935 if (file->alloc_sections > file->nb_sections)
936 {
937 file->sections = HeapReAlloc( GetProcessHeap(), 0, file->sections,
938 file->nb_sections * sizeof(file->sections[0]) );
939 file->alloc_sections = file->nb_sections;
940 }
941 if (file->alloc_fields > file->nb_fields)
942 {
943 file->fields = HeapReAlloc( GetProcessHeap(), 0, file->fields,
944 file->nb_fields * sizeof(file->fields[0]) );
945 file->alloc_fields = file->nb_fields;
946 }
948 (file->string_pos - file->strings) * sizeof(WCHAR) );
949
950 if (parser.error)
951 {
952 if (error_line) *error_line = parser.line_pos;
953 return parser.error;
954 }
955
956 /* find the [strings] section */
957 file->strings_section = find_section( file, Strings );
958
959 if (file->strings_section == -1 && parser.broken_line)
960 {
961 if (error_line) *error_line = parser.broken_line;
963 }
964
965 return 0;
966}
967
968
969/* append a child INF file to its parent list, in a thread-safe manner */
970static void append_inf_file( struct inf_file *parent, struct inf_file *child )
971{
972 struct inf_file **ppnext = &parent->next;
973 child->next = NULL;
974
975 for (;;)
976 {
977 struct inf_file *next = InterlockedCompareExchangePointer( (void **)ppnext, child, NULL );
978 if (!next) return;
979 ppnext = &next->next;
980 }
981}
982
983
984/***********************************************************************
985 * parse_file
986 *
987 * parse an INF file.
988 */
989static struct inf_file *parse_file( HANDLE handle, UINT *error_line, DWORD style )
990{
991 void *buffer;
992 DWORD err = 0;
993 struct inf_file *file;
994
997 if (!mapping) return NULL;
999 NtClose( mapping );
1000 if (!buffer) return NULL;
1001
1002 if (!(file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*file) )))
1003 {
1005 goto done;
1006 }
1007
1008 /* we won't need more strings space than the size of the file,
1009 * so we can preallocate it here
1010 */
1011 if (!(file->strings = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
1012 {
1014 goto done;
1015 }
1016 file->string_pos = file->strings;
1017 file->strings_section = -1;
1018
1019 if (!RtlIsTextUnicode( buffer, size, NULL ))
1020 {
1021 static const BYTE utf8_bom[3] = { 0xef, 0xbb, 0xbf };
1022 WCHAR *new_buff;
1024 UINT offset = 0;
1025
1026 if (size > sizeof(utf8_bom) && !memcmp( buffer, utf8_bom, sizeof(utf8_bom) ))
1027 {
1028 codepage = CP_UTF8;
1029 offset = sizeof(utf8_bom);
1030 }
1031
1032 if ((new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
1033 {
1035 size - offset, new_buff, size );
1036 err = parse_buffer( file, new_buff, new_buff + len, error_line );
1037 HeapFree( GetProcessHeap(), 0, new_buff );
1038 }
1039 }
1040 else
1041 {
1042 WCHAR *new_buff = buffer;
1043 /* UCS-16 files should start with the Unicode BOM; we should skip it */
1044 if (*new_buff == 0xfeff)
1045 new_buff++;
1046 err = parse_buffer( file, new_buff, (WCHAR *)((char *)buffer + size), error_line );
1047 }
1048
1049 if (!err) /* now check signature */
1050 {
1051 int version_index = find_section( file, Version );
1052 if (version_index != -1)
1053 {
1054 struct line *line = find_line( file, version_index, Signature );
1055 if (line && line->nb_fields > 0)
1056 {
1057 struct field *field = file->fields + line->first_field;
1058 if (!strcmpiW( field->text, Chicago )) goto done;
1059 if (!strcmpiW( field->text, WindowsNT )) goto done;
1060 if (!strcmpiW( field->text, Windows95 )) goto done;
1061 }
1062 }
1063 if (error_line) *error_line = 0;
1065 }
1066
1067 done:
1069 if (err)
1070 {
1071 if (file) free_inf_file( file );
1072 SetLastError( err );
1073 file = NULL;
1074 }
1075 return file;
1076}
1077
1078
1079/***********************************************************************
1080 * PARSER_get_inf_filename
1081 *
1082 * Retrieve the filename of an inf file.
1083 */
1085{
1086 struct inf_file *file = hinf;
1087 return file->filename;
1088}
1089
1090
1091/***********************************************************************
1092 * PARSER_get_src_root
1093 *
1094 * Retrieve the source directory of an inf file.
1095 */
1097{
1098 unsigned int len;
1099 const WCHAR *dir = get_inf_dir( hinf, &len );
1100 WCHAR *ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) );
1101 if (ret)
1102 {
1103 memcpy( ret, dir, len * sizeof(WCHAR) );
1104 ret[len] = 0;
1105 }
1106 return ret;
1107}
1108
1109
1110/***********************************************************************
1111 * PARSER_get_dest_dir
1112 *
1113 * retrieve a destination dir of the form "dirid,relative_path" in the given entry.
1114 * returned buffer must be freed by caller.
1115 */
1117{
1118 const WCHAR *dir;
1119 WCHAR *ptr, *ret;
1120 INT dirid;
1121 unsigned int len1;
1122 DWORD len2;
1123
1124 if (!SetupGetIntField( context, 1, &dirid )) return NULL;
1125 if (!(dir = get_dirid_subst( context->Inf, dirid, &len1 ))) return NULL;
1126 if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0;
1127 if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2+1) * sizeof(WCHAR) ))) return NULL;
1128 memcpy( ret, dir, len1 * sizeof(WCHAR) );
1129 ptr = ret + len1;
1130 if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\';
1131 if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0;
1132 return ret;
1133}
1134
1135
1136/***********************************************************************
1137 * SetupOpenInfFileA (SETUPAPI.@)
1138 */
1140{
1143
1144 classW.Buffer = NULL;
1145 if (class && !RtlCreateUnicodeStringFromAsciiz( &classW, class ))
1146 {
1148 return ret;
1149 }
1151 {
1152 ret = SetupOpenInfFileW( nameW.Buffer, classW.Buffer, style, error );
1154 }
1156 return ret;
1157}
1158
1159
1160static BOOL
1162 IN HINF hInf,
1163 OUT LPGUID ClassGuid,
1164 OUT PWSTR ClassName,
1165 IN DWORD ClassNameSize,
1167{
1168 DWORD requiredSize;
1169 WCHAR guidW[MAX_GUID_STRING_LEN + 1];
1170 BOOL ret = FALSE;
1171
1172 /* Read class Guid */
1173 if (!SetupGetLineTextW(NULL, hInf, Version, ClassGUID, guidW, sizeof(guidW), NULL))
1174 goto cleanup;
1175 guidW[37] = '\0'; /* Replace the } by a NULL character */
1176 if (UuidFromStringW(&guidW[1], ClassGuid) != RPC_S_OK)
1177 goto cleanup;
1178
1179 /* Read class name */
1180 ret = SetupGetLineTextW(NULL, hInf, Version, Class, ClassName, ClassNameSize, &requiredSize);
1181 if (ret && ClassName == NULL && ClassNameSize == 0)
1182 {
1183 if (RequiredSize)
1184 *RequiredSize = requiredSize;
1186 ret = FALSE;
1187 goto cleanup;
1188 }
1189 if (!ret)
1190 {
1192 {
1193 if (RequiredSize)
1194 *RequiredSize = requiredSize;
1195 goto cleanup;
1196 }
1197 else if (!SetupDiClassNameFromGuidW(ClassGuid, ClassName, ClassNameSize, &requiredSize))
1198 {
1200 {
1201 if (RequiredSize)
1202 *RequiredSize = requiredSize;
1203 goto cleanup;
1204 }
1205 /* Return a NULL class name */
1206 if (RequiredSize)
1207 *RequiredSize = 1;
1208 if (ClassNameSize < 1)
1209 {
1211 goto cleanup;
1212 }
1213 memcpy(ClassGuid, &GUID_NULL, sizeof(GUID));
1214 *ClassName = UNICODE_NULL;
1215 }
1216 }
1217
1218 ret = TRUE;
1219
1220cleanup:
1221 TRACE("Returning %d\n", ret);
1222 return ret;
1223}
1224
1225
1226/***********************************************************************
1227 * SetupOpenInfFileW (SETUPAPI.@)
1228 */
1230{
1231 struct inf_file *file = NULL;
1232 HANDLE handle;
1233 WCHAR *path, *p;
1234 UINT len;
1235
1236 TRACE("%s %s %lx %p\n", debugstr_w(name), debugstr_w(class), style, error);
1237
1238#ifdef __REACTOS__
1240 {
1242 return (HINF)INVALID_HANDLE_VALUE;
1243 }
1244 if (!name)
1245 {
1247 return (HINF)INVALID_HANDLE_VALUE;
1248 }
1249#endif // __REACTOS__
1250
1251 if (strchrW( name, '\\' ) || strchrW( name, '/' ))
1252 {
1253 if (!(len = GetFullPathNameW( name, 0, NULL, NULL ))) return INVALID_HANDLE_VALUE;
1254 if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
1255 {
1257 return INVALID_HANDLE_VALUE;
1258 }
1261 }
1262 else /* try Windows directory */
1263 {
1264 static const WCHAR Inf[] = {'\\','i','n','f','\\',0};
1265 static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};
1266
1267 len = GetWindowsDirectoryW( NULL, 0 ) + strlenW(name) + 12;
1268 if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
1269 {
1271 return INVALID_HANDLE_VALUE;
1272 }
1274 p = path + strlenW(path);
1275 strcpyW( p, Inf );
1276 strcatW( p, name );
1279 {
1280 strcpyW( p, System32 );
1281 strcatW( p, name );
1283 }
1284 }
1285
1287 {
1290 }
1291 if (!file)
1292 {
1293 HeapFree( GetProcessHeap(), 0, path );
1294 return INVALID_HANDLE_VALUE;
1295 }
1296 TRACE( "%s -> %p\n", debugstr_w(path), file );
1297 file->filename = path;
1298
1299 if (class)
1300 {
1301 GUID ClassGuid;
1302 LPWSTR ClassName = HeapAlloc(GetProcessHeap(), 0, (strlenW(class) + 1) * sizeof(WCHAR));
1303 if (!ClassName)
1304 {
1305 /* Not enough memory */
1308 return INVALID_HANDLE_VALUE;
1309 }
1310 else if (!PARSER_GetInfClassW((HINF)file, &ClassGuid, ClassName, strlenW(class) + 1, NULL))
1311 {
1312 /* Unable to get class name in .inf file */
1313 HeapFree(GetProcessHeap(), 0, ClassName);
1316 return INVALID_HANDLE_VALUE;
1317 }
1318 else if (strcmpW(class, ClassName) != 0)
1319 {
1320 /* Provided name name is not the expected one */
1321 HeapFree(GetProcessHeap(), 0, ClassName);
1324 return INVALID_HANDLE_VALUE;
1325 }
1326 HeapFree(GetProcessHeap(), 0, ClassName);
1327 }
1328
1329 SetLastError( 0 );
1330 return file;
1331}
1332
1333
1334/***********************************************************************
1335 * SetupOpenAppendInfFileA (SETUPAPI.@)
1336 */
1338{
1339 HINF child_hinf;
1340
1341 if (!name) return SetupOpenAppendInfFileW( NULL, parent_hinf, error );
1342 child_hinf = SetupOpenInfFileA( name, NULL, INF_STYLE_WIN4, error );
1343 if (child_hinf == INVALID_HANDLE_VALUE) return FALSE;
1344 append_inf_file( parent_hinf, child_hinf );
1345 TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_a(name), child_hinf );
1346 return TRUE;
1347}
1348
1349
1350/***********************************************************************
1351 * SetupOpenAppendInfFileW (SETUPAPI.@)
1352 */
1354{
1355 HINF child_hinf;
1356
1357 if (!name)
1358 {
1361 int idx = 1;
1362
1363 if (!SetupFindFirstLineW( parent_hinf, Version, LayoutFile, &context )) return FALSE;
1365 sizeof(filename)/sizeof(WCHAR), NULL ))
1366 {
1368 if (child_hinf == INVALID_HANDLE_VALUE) return FALSE;
1369 append_inf_file( parent_hinf, child_hinf );
1370 TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(filename), child_hinf );
1371 }
1372 return TRUE;
1373 }
1374 child_hinf = SetupOpenInfFileW( name, NULL, INF_STYLE_WIN4, error );
1375 if (child_hinf == INVALID_HANDLE_VALUE) return FALSE;
1376 append_inf_file( parent_hinf, child_hinf );
1377 TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(name), child_hinf );
1378 return TRUE;
1379}
1380
1381
1382/***********************************************************************
1383 * SetupOpenMasterInf (SETUPAPI.@)
1384 */
1386{
1387 static const WCHAR Layout[] = {'\\','i','n','f','\\', 'l', 'a', 'y', 'o', 'u', 't', '.', 'i', 'n', 'f', 0};
1389
1391 strcatW( Buffer, Layout );
1393}
1394
1395
1396
1397/***********************************************************************
1398 * SetupCloseInfFile (SETUPAPI.@)
1399 */
1401{
1402 struct inf_file *file = hinf;
1403
1404 if (!hinf || (hinf == INVALID_HANDLE_VALUE)) return;
1405
1407}
1408
1409
1410/***********************************************************************
1411 * SetupEnumInfSectionsA (SETUPAPI.@)
1412 */
1414{
1415 struct inf_file *file = hinf;
1416
1417 for (file = hinf; file; file = file->next)
1418 {
1419 if (index < file->nb_sections)
1420 {
1421 DWORD len = WideCharToMultiByte( CP_ACP, 0, file->sections[index]->name, -1,
1422 NULL, 0, NULL, NULL );
1423 if (need) *need = len;
1424 if (!buffer)
1425 {
1426 if (!size) return TRUE;
1428 return FALSE;
1429 }
1430 if (len > size)
1431 {
1433 return FALSE;
1434 }
1435 WideCharToMultiByte( CP_ACP, 0, file->sections[index]->name, -1, buffer, size, NULL, NULL );
1436 return TRUE;
1437 }
1438 index -= file->nb_sections;
1439 }
1441 return FALSE;
1442}
1443
1444
1445/***********************************************************************
1446 * SetupEnumInfSectionsW (SETUPAPI.@)
1447 */
1449{
1450 struct inf_file *file = hinf;
1451
1452 for (file = hinf; file; file = file->next)
1453 {
1454 if (index < file->nb_sections)
1455 {
1456 DWORD len = strlenW( file->sections[index]->name ) + 1;
1457 if (need) *need = len;
1458 if (!buffer)
1459 {
1460 if (!size) return TRUE;
1462 return FALSE;
1463 }
1464 if (len > size)
1465 {
1467 return FALSE;
1468 }
1469 memcpy( buffer, file->sections[index]->name, len * sizeof(WCHAR) );
1470 return TRUE;
1471 }
1472 index -= file->nb_sections;
1473 }
1475 return FALSE;
1476}
1477
1478
1479/***********************************************************************
1480 * SetupGetLineCountA (SETUPAPI.@)
1481 */
1483{
1484 UNICODE_STRING sectionW;
1485 LONG ret = -1;
1486
1487 if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, name ))
1489 else
1490 {
1491 ret = SetupGetLineCountW( hinf, sectionW.Buffer );
1492 RtlFreeUnicodeString( &sectionW );
1493 }
1494 return ret;
1495}
1496
1497
1498/***********************************************************************
1499 * SetupGetLineCountW (SETUPAPI.@)
1500 */
1502{
1503 struct inf_file *file = hinf;
1504 int section_index;
1505 LONG ret = -1;
1506
1507 for (file = hinf; file; file = file->next)
1508 {
1509 if ((section_index = find_section( file, section )) == -1) continue;
1510 if (ret == -1) ret = 0;
1511 ret += file->sections[section_index]->nb_lines;
1512 }
1513 TRACE( "(%p,%s) returning %d\n", hinf, debugstr_w(section), ret );
1514 SetLastError( (ret == -1) ? ERROR_SECTION_NOT_FOUND : 0 );
1515 return ret;
1516}
1517
1518
1519/***********************************************************************
1520 * SetupGetLineByIndexA (SETUPAPI.@)
1521 */
1523{
1524 UNICODE_STRING sectionW;
1525 BOOL ret = FALSE;
1526
1527 if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1529 else
1530 {
1531 ret = SetupGetLineByIndexW( hinf, sectionW.Buffer, index, context );
1532 RtlFreeUnicodeString( &sectionW );
1533 }
1534 return ret;
1535}
1536
1537
1538/***********************************************************************
1539 * SetupGetLineByIndexW (SETUPAPI.@)
1540 */
1542{
1543 struct inf_file *file = hinf;
1544 int section_index;
1545
1546 for (file = hinf; file; file = file->next)
1547 {
1548 if ((section_index = find_section( file, section )) == -1) continue;
1549 if (index < file->sections[section_index]->nb_lines)
1550 {
1551 context->Inf = hinf;
1552 context->CurrentInf = file;
1553 context->Section = section_index;
1554 context->Line = index;
1555 SetLastError( 0 );
1556 TRACE( "(%p,%s): returning %d/%d\n",
1557 hinf, debugstr_w(section), section_index, index );
1558 return TRUE;
1559 }
1560 index -= file->sections[section_index]->nb_lines;
1561 }
1562 TRACE( "(%p,%s) not found\n", hinf, debugstr_w(section) );
1564 return FALSE;
1565}
1566
1567
1568/***********************************************************************
1569 * SetupFindFirstLineA (SETUPAPI.@)
1570 */
1572{
1573 UNICODE_STRING sectionW, keyW;
1574 BOOL ret = FALSE;
1575
1576 if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
1577 {
1579 return FALSE;
1580 }
1581
1582 if (!key) ret = SetupFindFirstLineW( hinf, sectionW.Buffer, NULL, context );
1583 else
1584 {
1586 {
1587 ret = SetupFindFirstLineW( hinf, sectionW.Buffer, keyW.Buffer, context );
1588 RtlFreeUnicodeString( &keyW );
1589 }
1591 }
1592 RtlFreeUnicodeString( &sectionW );
1593 return ret;
1594}
1595
1596
1597/***********************************************************************
1598 * SetupFindFirstLineW (SETUPAPI.@)
1599 */
1601{
1602 struct inf_file *file;
1603 int section_index;
1604
1605 for (file = hinf; file; file = file->next)
1606 {
1607 if ((section_index = find_section( file, section )) == -1) continue;
1608 if (key)
1609 {
1611 ctx.Inf = hinf;
1612 ctx.CurrentInf = file;
1613 ctx.Section = section_index;
1614 ctx.Line = -1;
1616 }
1617 if (file->sections[section_index]->nb_lines)
1618 {
1619 context->Inf = hinf;
1620 context->CurrentInf = file;
1621 context->Section = section_index;
1622 context->Line = 0;
1623 SetLastError( 0 );
1624 TRACE( "(%p,%s,%s): returning %d/0\n",
1625 hinf, debugstr_w(section), debugstr_w(key), section_index );
1626 return TRUE;
1627 }
1628 }
1629 TRACE( "(%p,%s,%s): not found\n", hinf, debugstr_w(section), debugstr_w(key) );
1631 return FALSE;
1632}
1633
1634
1635/***********************************************************************
1636 * SetupFindNextLine (SETUPAPI.@)
1637 */
1639{
1640 struct inf_file *file = context_in->CurrentInf;
1641 struct section *section;
1642
1643 if (context_in->Section >= file->nb_sections) goto error;
1644
1645 section = file->sections[context_in->Section];
1646 if (context_in->Line+1 < section->nb_lines)
1647 {
1648 if (context_out != context_in) *context_out = *context_in;
1649 context_out->Line++;
1650 SetLastError( 0 );
1651 return TRUE;
1652 }
1653
1654 /* now search the appended files */
1655
1656 for (file = file->next; file; file = file->next)
1657 {
1658 int section_index = find_section( file, section->name );
1659 if (section_index == -1) continue;
1660 if (file->sections[section_index]->nb_lines)
1661 {
1662 context_out->Inf = context_in->Inf;
1663 context_out->CurrentInf = file;
1664 context_out->Section = section_index;
1665 context_out->Line = 0;
1666 SetLastError( 0 );
1667 return TRUE;
1668 }
1669 }
1670 error:
1672 return FALSE;
1673}
1674
1675
1676/***********************************************************************
1677 * SetupFindNextMatchLineA (SETUPAPI.@)
1678 */
1680 PINFCONTEXT context_out )
1681{
1682 UNICODE_STRING keyW;
1683 BOOL ret = FALSE;
1684
1685 if (!key) return SetupFindNextLine( context_in, context_out );
1686
1689 else
1690 {
1691 ret = SetupFindNextMatchLineW( context_in, keyW.Buffer, context_out );
1692 RtlFreeUnicodeString( &keyW );
1693 }
1694 return ret;
1695}
1696
1697
1698/***********************************************************************
1699 * SetupFindNextMatchLineW (SETUPAPI.@)
1700 */
1702 PINFCONTEXT context_out )
1703{
1704 struct inf_file *file = context_in->CurrentInf;
1705 struct section *section;
1706 struct line *line;
1707 unsigned int i;
1708
1709 if (!key) return SetupFindNextLine( context_in, context_out );
1710
1711 if (context_in->Section >= file->nb_sections) goto error;
1712
1713 section = file->sections[context_in->Section];
1714
1715 for (i = context_in->Line+1, line = &section->lines[i]; i < section->nb_lines; i++, line++)
1716 {
1717 if (line->key_field == -1) continue;
1718 if (!strcmpiW( key, file->fields[line->key_field].text ))
1719 {
1720 if (context_out != context_in) *context_out = *context_in;
1721 context_out->Line = i;
1722 SetLastError( 0 );
1723 TRACE( "(%p,%s,%s): returning %d\n",
1725 return TRUE;
1726 }
1727 }
1728
1729 /* now search the appended files */
1730
1731 for (file = file->next; file; file = file->next)
1732 {
1733 int section_index = find_section( file, section->name );
1734 if (section_index == -1) continue;
1735 section = file->sections[section_index];
1736 for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
1737 {
1738 if (line->key_field == -1) continue;
1739 if (!strcmpiW( key, file->fields[line->key_field].text ))
1740 {
1741 context_out->Inf = context_in->Inf;
1742 context_out->CurrentInf = file;
1743 context_out->Section = section_index;
1744 context_out->Line = i;
1745 SetLastError( 0 );
1746 TRACE( "(%p,%s,%s): returning %d/%d\n",
1747 file, debugstr_w(section->name), debugstr_w(key), section_index, i );
1748 return TRUE;
1749 }
1750 }
1751 }
1752 TRACE( "(%p,%s,%s): not found\n",
1753 context_in->CurrentInf, debugstr_w(section->name), debugstr_w(key) );
1754 error:
1756 return FALSE;
1757}
1758
1759
1760/***********************************************************************
1761 * SetupGetLineTextW (SETUPAPI.@)
1762 */
1765{
1766 struct inf_file *file;
1767 struct line *line;
1768 struct field *field;
1769 int i;
1770 DWORD total = 0;
1771
1772 if (!context)
1773 {
1774 INFCONTEXT new_context;
1775 if (!SetupFindFirstLineW( hinf, section_name, key_name, &new_context )) return FALSE;
1776 file = new_context.CurrentInf;
1777 line = get_line( file, new_context.Section, new_context.Line );
1778 }
1779 else
1780 {
1781 file = context->CurrentInf;
1782 if (!(line = get_line( file, context->Section, context->Line )))
1783 {
1785 return FALSE;
1786 }
1787 }
1788
1789 for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
1790 total += PARSER_string_substW( file, field->text, NULL, 0 ) + 1;
1791
1792 if (required) *required = total;
1793 if (buffer)
1794 {
1795 if (total > size)
1796 {
1798 return FALSE;
1799 }
1800 for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
1801 {
1802 unsigned int len = PARSER_string_substW( file, field->text, buffer, size );
1803 if (i+1 < line->nb_fields) buffer[len] = ',';
1804 buffer += len + 1;
1805 }
1806 }
1807 return TRUE;
1808}
1809
1810
1811/***********************************************************************
1812 * SetupGetLineTextA (SETUPAPI.@)
1813 */
1815 PCSTR key_name, PSTR buffer, DWORD size, PDWORD required )
1816{
1817 struct inf_file *file;
1818 struct line *line;
1819 struct field *field;
1820 int i;
1821 DWORD total = 0;
1822
1823 if (!context)
1824 {
1825 INFCONTEXT new_context;
1826 if (!SetupFindFirstLineA( hinf, section_name, key_name, &new_context )) return FALSE;
1827 file = new_context.CurrentInf;
1828 line = get_line( file, new_context.Section, new_context.Line );
1829 }
1830 else
1831 {
1832 file = context->CurrentInf;
1833 if (!(line = get_line( file, context->Section, context->Line )))
1834 {
1836 return FALSE;
1837 }
1838 }
1839
1840 for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
1841 total += PARSER_string_substA( file, field->text, NULL, 0 ) + 1;
1842
1843 if (required) *required = total;
1844 if (buffer)
1845 {
1846 if (total > size)
1847 {
1849 return FALSE;
1850 }
1851 for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
1852 {
1853 unsigned int len = PARSER_string_substA( file, field->text, buffer, size );
1854 if (i+1 < line->nb_fields) buffer[len] = ',';
1855 buffer += len + 1;
1856 }
1857 }
1858 return TRUE;
1859}
1860
1861
1862/***********************************************************************
1863 * SetupGetFieldCount (SETUPAPI.@)
1864 */
1866{
1867 struct inf_file *file = context->CurrentInf;
1868 struct line *line = get_line( file, context->Section, context->Line );
1869
1870 if (!line) return 0;
1871 return line->nb_fields;
1872}
1873
1874
1875/***********************************************************************
1876 * SetupGetStringFieldA (SETUPAPI.@)
1877 */
1879 DWORD size, PDWORD required )
1880{
1881 struct inf_file *file = context->CurrentInf;
1882 struct field *field = get_field( file, context->Section, context->Line, index );
1883 unsigned int len;
1884
1885 SetLastError(0);
1888 if (required) *required = len + 1;
1889 if (buffer)
1890 {
1891 if (size <= len)
1892 {
1894 return FALSE;
1895 }
1897
1898 TRACE( "context %p/%p/%d/%d index %d returning %s\n",
1899 context->Inf, context->CurrentInf, context->Section, context->Line,
1901 }
1902 return TRUE;
1903}
1904
1905
1906/***********************************************************************
1907 * SetupGetStringFieldW (SETUPAPI.@)
1908 */
1910 DWORD size, PDWORD required )
1911{
1912 struct inf_file *file = context->CurrentInf;
1913 struct field *field = get_field( file, context->Section, context->Line, index );
1914 unsigned int len;
1915
1916 SetLastError(0);
1919 if (required) *required = len + 1;
1920 if (buffer)
1921 {
1922 if (size <= len)
1923 {
1925 return FALSE;
1926 }
1928
1929 TRACE( "context %p/%p/%d/%d index %d returning %s\n",
1930 context->Inf, context->CurrentInf, context->Section, context->Line,
1932 }
1933 return TRUE;
1934}
1935
1936
1937/***********************************************************************
1938 * SetupGetIntField (SETUPAPI.@)
1939 */
1941{
1942 char localbuff[20];
1943 char *end, *buffer = localbuff;
1944 DWORD required;
1945 INT res;
1946 BOOL ret;
1947
1948 if (!(ret = SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required )))
1949 {
1951 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE;
1952 if (!(ret = SetupGetStringFieldA( context, index, buffer, required, NULL ))) goto done;
1953 }
1954 /* The call to SetupGetStringFieldA succeeded. If buffer is empty we have an optional field */
1955 if (!*buffer) *result = 0;
1956 else
1957 {
1958 res = strtol( buffer, &end, 0 );
1959 if (end != buffer && !*end) *result = res;
1960 else
1961 {
1963 ret = FALSE;
1964 }
1965 }
1966
1967 done:
1968 if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer );
1969 return ret;
1970}
1971
1972
1973/***********************************************************************
1974 * SetupGetBinaryField (SETUPAPI.@)
1975 */
1977 DWORD size, LPDWORD required )
1978{
1979 struct inf_file *file = context->CurrentInf;
1980 struct line *line = get_line( file, context->Section, context->Line );
1981 struct field *field;
1982 int i;
1983
1984 if (!line)
1985 {
1987 return FALSE;
1988 }
1989 if (!index || index > line->nb_fields)
1990 {
1992 return FALSE;
1993 }
1994 index--; /* fields start at 0 */
1995 if (required) *required = line->nb_fields - index;
1996 if (!buffer) return TRUE;
1997 if (size < line->nb_fields - index)
1998 {
2000 return FALSE;
2001 }
2002 field = &file->fields[line->first_field + index];
2003 for (i = index; i < line->nb_fields; i++, field++)
2004 {
2005 const WCHAR *p;
2006 DWORD value = 0;
2007 for (p = field->text; *p && isxdigitW(*p); p++)
2008 {
2009 if ((value <<= 4) > 255)
2010 {
2012 return FALSE;
2013 }
2014 if (*p <= '9') value |= (*p - '0');
2015 else value |= (tolowerW(*p) - 'a' + 10);
2016 }
2017 buffer[i - index] = value;
2018 }
2019 if (TRACE_ON(setupapi))
2020 {
2021 TRACE( "%p/%p/%d/%d index %d returning:\n",
2022 context->Inf, context->CurrentInf, context->Section, context->Line, index );
2023 for (i = index; i < line->nb_fields; i++) TRACE( " %02x\n", buffer[i - index] );
2024 }
2025 return TRUE;
2026}
2027
2028
2029/***********************************************************************
2030 * SetupGetMultiSzFieldA (SETUPAPI.@)
2031 */
2033 DWORD size, LPDWORD required )
2034{
2035 struct inf_file *file = context->CurrentInf;
2036 struct line *line = get_line( file, context->Section, context->Line );
2037 struct field *field;
2038 unsigned int len;
2039 int i;
2040 DWORD total = 1;
2041
2042 if (!line)
2043 {
2045 return FALSE;
2046 }
2047 if (!index || index > line->nb_fields)
2048 {
2050 return FALSE;
2051 }
2052 index--; /* fields start at 0 */
2053 field = &file->fields[line->first_field + index];
2054 for (i = index; i < line->nb_fields; i++, field++)
2055 {
2056 if (!(len = PARSER_string_substA( file, field->text, NULL, 0 ))) break;
2057 total += len + 1;
2058 }
2059
2060 if (required) *required = total;
2061 if (!buffer) return TRUE;
2062 if (total > size)
2063 {
2065 return FALSE;
2066 }
2067 field = &file->fields[line->first_field + index];
2068 for (i = index; i < line->nb_fields; i++, field++)
2069 {
2070 if (!(len = PARSER_string_substA( file, field->text, buffer, size ))) break;
2071 buffer += len + 1;
2072 }
2073 *buffer = 0; /* add final null */
2074 return TRUE;
2075}
2076
2077
2078/***********************************************************************
2079 * SetupGetMultiSzFieldW (SETUPAPI.@)
2080 */
2082 DWORD size, LPDWORD required )
2083{
2084 struct inf_file *file = context->CurrentInf;
2085 struct line *line = get_line( file, context->Section, context->Line );
2086 struct field *field;
2087 unsigned int len;
2088 int i;
2089 DWORD total = 1;
2090
2091 if (!line)
2092 {
2094 return FALSE;
2095 }
2096 if (!index || index > line->nb_fields)
2097 {
2099 return FALSE;
2100 }
2101 index--; /* fields start at 0 */
2102 field = &file->fields[line->first_field + index];
2103 for (i = index; i < line->nb_fields; i++, field++)
2104 {
2105 if (!(len = PARSER_string_substW( file, field->text, NULL, 0 ))) break;
2106 total += len + 1;
2107 }
2108
2109 if (required) *required = total;
2110 if (!buffer) return TRUE;
2111 if (total > size)
2112 {
2114 return FALSE;
2115 }
2116 field = &file->fields[line->first_field + index];
2117 for (i = index; i < line->nb_fields; i++, field++)
2118 {
2119 if (!(len = PARSER_string_substW( file, field->text, buffer, size ))) break;
2120 buffer += len + 1;
2121 }
2122 *buffer = 0; /* add final null */
2123 return TRUE;
2124}
2125
2126/***********************************************************************
2127 * pSetupGetField (SETUPAPI.@)
2128 */
2130{
2131 struct inf_file *file = context->CurrentInf;
2132 struct field *field = get_field( file, context->Section, context->Line, index );
2133
2134 if (!field)
2135 {
2137 return NULL;
2138 }
2139 return field->text;
2140}
2141
2142/***********************************************************************
2143 * SetupGetInfFileListW (SETUPAPI.@)
2144 */
2147 IN PCWSTR DirectoryPath OPTIONAL,
2148 IN DWORD InfStyle,
2149 IN OUT PWSTR ReturnBuffer OPTIONAL,
2152{
2153 HANDLE hSearch;
2154 LPWSTR pFullFileName = NULL;
2155 LPWSTR pFileName; /* Pointer into pFullFileName buffer */
2156 LPWSTR pBuffer = ReturnBuffer;
2157 WIN32_FIND_DATAW wfdFileInfo;
2158 size_t len;
2159 DWORD requiredSize = 0;
2160 BOOL ret = FALSE;
2161
2162 TRACE("%s %lx %p %ld %p\n", debugstr_w(DirectoryPath), InfStyle,
2163 ReturnBuffer, ReturnBufferSize, RequiredSize);
2164
2165 if (InfStyle & ~(INF_STYLE_OLDNT | INF_STYLE_WIN4))
2166 {
2167 TRACE("Unknown flags: 0x%08lx\n", InfStyle & ~(INF_STYLE_OLDNT | INF_STYLE_WIN4));
2169 goto cleanup;
2170 }
2171 else if (ReturnBufferSize == 0 && ReturnBuffer != NULL)
2172 {
2174 goto cleanup;
2175 }
2176 else if (ReturnBufferSize > 0 && ReturnBuffer == NULL)
2177 {
2179 goto cleanup;
2180 }
2181
2182 /* Allocate memory for file filter */
2183 if (DirectoryPath != NULL)
2184 /* "DirectoryPath\" form */
2185 len = strlenW(DirectoryPath) + 1 + 1;
2186 else
2187 /* "%SYSTEMROOT%\Inf\" form */
2188 len = MAX_PATH + 1 + strlenW(InfDirectory) + 1;
2189 len += MAX_PATH; /* To contain file name or "*.inf" string */
2190 pFullFileName = MyMalloc(len * sizeof(WCHAR));
2191 if (pFullFileName == NULL)
2192 {
2194 goto cleanup;
2195 }
2196
2197 /* Fill file filter buffer */
2198 if (DirectoryPath)
2199 {
2200 strcpyW(pFullFileName, DirectoryPath);
2201 if (*pFullFileName && pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2202 strcatW(pFullFileName, BackSlash);
2203 }
2204 else
2205 {
2206 len = GetSystemWindowsDirectoryW(pFullFileName, MAX_PATH);
2207 if (len == 0 || len > MAX_PATH)
2208 goto cleanup;
2209 if (pFullFileName[strlenW(pFullFileName) - 1] != '\\')
2210 strcatW(pFullFileName, BackSlash);
2211 strcatW(pFullFileName, InfDirectory);
2212 }
2213 pFileName = &pFullFileName[strlenW(pFullFileName)];
2214
2215 /* Search for the first file */
2216 strcpyW(pFileName, InfFileSpecification);
2217 hSearch = FindFirstFileW(pFullFileName, &wfdFileInfo);
2218 if (hSearch == INVALID_HANDLE_VALUE)
2219 {
2220 TRACE("No file returned by %s\n", debugstr_w(pFullFileName));
2221 goto cleanup;
2222 }
2223
2224 do
2225 {
2226 HINF hInf;
2227
2228 strcpyW(pFileName, wfdFileInfo.cFileName);
2229 hInf = SetupOpenInfFileW(
2230 pFullFileName,
2231 NULL, /* Inf class */
2232 InfStyle,
2233 NULL /* Error line */);
2234 if (hInf == INVALID_HANDLE_VALUE)
2235 {
2237 {
2238 /* InfStyle was not correct. Skip this file */
2239 continue;
2240 }
2241 TRACE("Invalid .inf file %s\n", debugstr_w(pFullFileName));
2242 continue;
2243 }
2244
2245 len = strlenW(wfdFileInfo.cFileName) + 1;
2246 requiredSize += (DWORD)len;
2247 if (requiredSize <= ReturnBufferSize)
2248 {
2249 strcpyW(pBuffer, wfdFileInfo.cFileName);
2250 pBuffer = &pBuffer[len];
2251 }
2252 SetupCloseInfFile(hInf);
2253 } while (FindNextFileW(hSearch, &wfdFileInfo));
2254 FindClose(hSearch);
2255
2256 requiredSize += 1; /* Final NULL char */
2257 if (requiredSize <= ReturnBufferSize)
2258 {
2259 *pBuffer = '\0';
2260 ret = TRUE;
2261 }
2262 else
2263 {
2265 ret = FALSE;
2266 }
2267 if (RequiredSize)
2268 *RequiredSize = requiredSize;
2269
2270cleanup:
2271 MyFree(pFullFileName);
2272 return ret;
2273}
2274
2275/***********************************************************************
2276 * SetupGetInfFileListA (SETUPAPI.@)
2277 */
2280 IN PCSTR DirectoryPath OPTIONAL,
2281 IN DWORD InfStyle,
2282 IN OUT PSTR ReturnBuffer OPTIONAL,
2285{
2286 PWSTR DirectoryPathW = NULL;
2287 PWSTR ReturnBufferW = NULL;
2288 BOOL ret = FALSE;
2289
2290 TRACE("%s %lx %p %ld %p\n", debugstr_a(DirectoryPath), InfStyle,
2291 ReturnBuffer, ReturnBufferSize, RequiredSize);
2292
2293 if (DirectoryPath != NULL)
2294 {
2295 DirectoryPathW = pSetupMultiByteToUnicode(DirectoryPath, CP_ACP);
2296 if (DirectoryPathW == NULL) goto Cleanup;
2297 }
2298
2299 if (ReturnBuffer != NULL && ReturnBufferSize != 0)
2300 {
2301 ReturnBufferW = MyMalloc(ReturnBufferSize * sizeof(WCHAR));
2302 if (ReturnBufferW == NULL) goto Cleanup;
2303 }
2304
2305 ret = SetupGetInfFileListW(DirectoryPathW, InfStyle, ReturnBufferW, ReturnBufferSize, RequiredSize);
2306
2307 if (ret && ReturnBufferW != NULL)
2308 {
2309 ret = WideCharToMultiByte(CP_ACP, 0, ReturnBufferW, -1, ReturnBuffer, ReturnBufferSize, NULL, NULL) != 0;
2310 }
2311
2312Cleanup:
2313 MyFree(DirectoryPathW);
2314 MyFree(ReturnBufferW);
2315
2316 return ret;
2317}
2318
2319/***********************************************************************
2320 * SetupDiGetINFClassW (SETUPAPI.@)
2321 */
2324 IN PCWSTR InfName,
2325 OUT LPGUID ClassGuid,
2326 OUT PWSTR ClassName,
2327 IN DWORD ClassNameSize,
2329{
2331 BOOL ret = FALSE;
2332
2333 TRACE("%s %p %p %ld %p\n", debugstr_w(InfName), ClassGuid,
2334 ClassName, ClassNameSize, RequiredSize);
2335
2336 if (!InfName || !ClassGuid || !ClassName || ClassNameSize == 0)
2337 {
2339 return FALSE;
2340 }
2341
2342 /* Open .inf file */
2343 hInf = SetupOpenInfFileW(InfName, NULL, INF_STYLE_WIN4, NULL);
2344 if (hInf == INVALID_HANDLE_VALUE)
2345 goto cleanup;
2346
2347 ret = PARSER_GetInfClassW(hInf, ClassGuid, ClassName, ClassNameSize, RequiredSize);
2348
2349cleanup:
2350 if (hInf != INVALID_HANDLE_VALUE)
2351 SetupCloseInfFile(hInf);
2352
2353 TRACE("Returning %d\n", ret);
2354 return ret;
2355}
2356
2357/***********************************************************************
2358 * SetupDiGetINFClassA (SETUPAPI.@)
2359 */
2361 IN PCSTR InfName,
2362 OUT LPGUID ClassGuid,
2363 OUT PSTR ClassName,
2364 IN DWORD ClassNameSize,
2366{
2367 PWSTR InfNameW = NULL;
2368 PWSTR ClassNameW = NULL;
2369 BOOL ret = FALSE;
2370
2371 TRACE("%s %p %p %ld %p\n", debugstr_a(InfName), ClassGuid,
2372 ClassName, ClassNameSize, RequiredSize);
2373
2374 if (InfName != NULL)
2375 {
2376 InfNameW = pSetupMultiByteToUnicode(InfName, CP_ACP);
2377 if (InfNameW == NULL) goto Cleanup;
2378 }
2379
2380 if (ClassName != NULL && ClassNameSize != 0)
2381 {
2382 ClassNameW = MyMalloc(ClassNameSize * sizeof(WCHAR));
2383 if (ClassNameW == NULL) goto Cleanup;
2384 }
2385
2386 ret = SetupDiGetINFClassW(InfNameW, ClassGuid, ClassNameW, ClassNameSize, RequiredSize);
2387
2388 if (ret && ClassNameW != NULL)
2389 {
2390 ret = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName, ClassNameSize, NULL, NULL) != 0;
2391 }
2392
2393Cleanup:
2394 MyFree(InfNameW);
2395 MyFree(ClassNameW);
2396
2397 return ret;
2398}
2399
2401 IN HINF hInf,
2402 IN LPCWSTR pStr,
2405{
2406 struct inf_file *file = (struct inf_file *)hInf;
2407 size_t len = strlenW(pStr);
2408 unsigned int i;
2409
2410 for (i = 0; i < file->nb_sections; i++)
2411 {
2412 if (strncmpiW(pStr, file->sections[i]->name, len) == 0)
2413 {
2414 if (!Callback(file->sections[i]->name, Context))
2415 return FALSE;
2416 }
2417 }
2418 return TRUE;
2419}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
parser_state
Definition: import.c:59
static WCHAR *(* get_line)(FILE *)
Definition: import.c:55
static const WCHAR nameW[]
Definition: main.c:49
#define index(s, c)
Definition: various.h:29
Definition: bufpool.h:45
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
const WCHAR * DIRID_get_string(int dirid)
Definition: dirid.c:159
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAX_GUID_STRING_LEN
Definition: apphelp.c:29
unsigned int idx
Definition: utils.c:41
static const WCHAR Strings[]
Definition: reg.c:35
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:744
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define GENERIC_READ
Definition: compat.h:135
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define FILE_MAP_READ
Definition: compat.h:776
#define WideCharToMultiByte
Definition: compat.h:111
#define MapViewOfFile
Definition: compat.h:745
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2397
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
const WCHAR * text
Definition: package.c:1794
BOOL WINAPI SetupDiClassNameFromGuidW(const GUID *ClassGuid, PWSTR ClassName, DWORD ClassNameSize, PDWORD RequiredSize)
Definition: devinst.c:1067
LPWSTR WINAPI pSetupMultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage)
Definition: misc.c:281
LPVOID WINAPI MyMalloc(DWORD dwSize)
Definition: misc.c:147
VOID WINAPI MyFree(LPVOID lpMem)
Definition: misc.c:128
BOOL WINAPI SetupFindNextMatchLineA(PINFCONTEXT context_in, PCSTR key, PINFCONTEXT context_out)
Definition: parser.c:1679
static const WCHAR * key_name_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:677
#define MAX_FIELD_LEN
Definition: parser.c:37
static const WCHAR * value_name_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:731
const WCHAR * PARSER_get_inf_filename(HINF hinf)
Definition: parser.c:1084
static int add_section(struct inf_file *file, const WCHAR *name)
Definition: parser.c:206
BOOL WINAPI SetupEnumInfSectionsW(HINF hinf, UINT index, PWSTR buffer, DWORD size, DWORD *need)
Definition: parser.c:1448
WCHAR * PARSER_get_src_root(HINF hinf)
Definition: parser.c:1096
HINF WINAPI SetupOpenInfFileW(PCWSTR name, PCWSTR class, DWORD style, UINT *error)
Definition: parser.c:1229
static const WCHAR ClassGUID[]
Definition: parser.c:31
static struct field * add_field_from_token(struct parser *parser, BOOL is_key)
Definition: parser.c:566
LONG WINAPI SetupGetLineCountW(HINF hinf, PCWSTR section)
Definition: parser.c:1501
static void push_state(struct parser *parser, enum parser_state state)
Definition: parser.c:484
static BOOL is_eol(const struct parser *parser, const WCHAR *ptr)
Definition: parser.c:516
static const WCHAR * section_name_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:656
void WINAPI SetupCloseInfFile(HINF hinf)
Definition: parser.c:1400
DWORD WINAPI SetupGetFieldCount(PINFCONTEXT context)
Definition: parser.c:1865
BOOL WINAPI SetupGetMultiSzFieldW(PINFCONTEXT context, DWORD index, PWSTR buffer, DWORD size, LPDWORD required)
Definition: parser.c:2081
static WCHAR * push_string(struct inf_file *file, const WCHAR *string)
Definition: parser.c:474
BOOL WINAPI SetupGetBinaryField(PINFCONTEXT context, DWORD index, BYTE *buffer, DWORD size, LPDWORD required)
Definition: parser.c:1976
static const WCHAR WindowsNT[]
Definition: parser.c:143
static void append_inf_file(struct inf_file *parent, struct inf_file *child)
Definition: parser.c:970
static const WCHAR * get_dirid_subst(const struct inf_file *file, int dirid, unsigned int *len)
Definition: parser.c:296
static const WCHAR * leading_spaces_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:847
static void * grow_array(void *array, unsigned int *count, size_t elem)
Definition: parser.c:148
#define MAX_STRING_LEN
Definition: parser.c:39
static void close_current_line(struct parser *parser)
Definition: parser.c:602
static BOOL is_eof(const struct parser *parser, const WCHAR *ptr)
Definition: parser.c:509
static void pop_state(struct parser *parser)
Definition: parser.c:492
static BOOL PARSER_GetInfClassW(IN HINF hInf, OUT LPGUID ClassGuid, OUT PWSTR ClassName, IN DWORD ClassNameSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:1161
static unsigned int PARSER_string_substA(const struct inf_file *file, const WCHAR *text, char *buffer, unsigned int size)
Definition: parser.c:456
static const WCHAR Signature[]
Definition: parser.c:141
static struct field * add_field(struct inf_file *file, const WCHAR *text)
Definition: parser.c:280
static const WCHAR * get_inf_dir(const struct inf_file *file, unsigned int *len)
Definition: parser.c:168
static const WCHAR Chicago[]
Definition: parser.c:142
BOOL WINAPI SetupFindFirstLineW(HINF hinf, PCWSTR section, PCWSTR key, INFCONTEXT *context)
Definition: parser.c:1600
static const WCHAR LayoutFile[]
Definition: parser.c:145
BOOL WINAPI SetupFindNextLine(PINFCONTEXT context_in, PINFCONTEXT context_out)
Definition: parser.c:1638
static enum parser_state set_state(struct parser *parser, enum parser_state state)
Definition: parser.c:500
static int add_section_from_token(struct parser *parser)
Definition: parser.c:540
static int find_section(const struct inf_file *file, const WCHAR *name)
Definition: parser.c:177
#define CONTROL_Z
Definition: parser.c:35
static const WCHAR * line_start_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:617
static const WCHAR * get_string_subst(const struct inf_file *file, const WCHAR *str, unsigned int *len, BOOL no_trailing_slash)
Definition: parser.c:309
const WCHAR *(* parser_state_func)(struct parser *parser, const WCHAR *pos)
Definition: parser.c:112
BOOL WINAPI SetupDiGetINFClassA(IN PCSTR InfName, OUT LPGUID ClassGuid, OUT PSTR ClassName, IN DWORD ClassNameSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2360
BOOL WINAPI SetupGetStringFieldW(PINFCONTEXT context, DWORD index, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1909
BOOL EnumerateSectionsStartingWith(IN HINF hInf, IN LPCWSTR pStr, IN FIND_CALLBACK Callback, IN PVOID Context)
Definition: parser.c:2400
static const WCHAR BackSlash[]
Definition: parser.c:29
WCHAR * PARSER_get_dest_dir(INFCONTEXT *context)
Definition: parser.c:1116
BOOL WINAPI SetupGetIntField(PINFCONTEXT context, DWORD index, PINT result)
Definition: parser.c:1940
BOOL WINAPI SetupOpenAppendInfFileA(PCSTR name, HINF parent_hinf, UINT *error)
Definition: parser.c:1337
static const WCHAR Windows95[]
Definition: parser.c:144
BOOL WINAPI SetupGetLineByIndexW(HINF hinf, PCWSTR section, DWORD index, INFCONTEXT *context)
Definition: parser.c:1541
BOOL WINAPI SetupFindFirstLineA(HINF hinf, PCSTR section, PCSTR key, INFCONTEXT *context)
Definition: parser.c:1571
BOOL WINAPI SetupGetMultiSzFieldA(PINFCONTEXT context, DWORD index, PSTR buffer, DWORD size, LPDWORD required)
Definition: parser.c:2032
HINF WINAPI SetupOpenInfFileA(PCSTR name, PCSTR class, DWORD style, UINT *error)
Definition: parser.c:1139
LPCWSTR WINAPI pSetupGetField(PINFCONTEXT context, DWORD index)
Definition: parser.c:2129
BOOL WINAPI SetupEnumInfSectionsA(HINF hinf, UINT index, PSTR buffer, DWORD size, DWORD *need)
Definition: parser.c:1413
BOOL WINAPI SetupGetLineTextA(PINFCONTEXT context, HINF hinf, PCSTR section_name, PCSTR key_name, PSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1814
static struct inf_file * parse_file(HANDLE handle, UINT *error_line, DWORD style)
Definition: parser.c:989
static struct line * add_line(struct inf_file *file, int section_index)
Definition: parser.c:225
static const WCHAR * eol_backslash_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:784
@ NB_PARSER_STATES
Definition: parser.c:91
@ SECTION_NAME
Definition: parser.c:83
@ TRAILING_SPACES
Definition: parser.c:89
@ QUOTES
Definition: parser.c:87
@ LINE_START
Definition: parser.c:82
@ EOL_BACKSLASH
Definition: parser.c:86
@ COMMENT
Definition: parser.c:90
@ LEADING_SPACES
Definition: parser.c:88
@ KEY_NAME
Definition: parser.c:84
@ VALUE_NAME
Definition: parser.c:85
static struct field * get_field(struct inf_file *file, int section_index, int line_index, int field_index)
Definition: parser.c:262
static const WCHAR * quotes_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:817
BOOL WINAPI SetupOpenAppendInfFileW(PCWSTR name, HINF parent_hinf, UINT *error)
Definition: parser.c:1353
BOOL WINAPI SetupGetInfFileListW(IN PCWSTR DirectoryPath OPTIONAL, IN DWORD InfStyle, IN OUT PWSTR ReturnBuffer OPTIONAL, IN DWORD ReturnBufferSize OPTIONAL, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2146
static unsigned int PARSER_string_substW(const struct inf_file *file, const WCHAR *text, WCHAR *buffer, unsigned int size)
Definition: parser.c:403
LONG WINAPI SetupGetLineCountA(HINF hinf, PCSTR name)
Definition: parser.c:1482
static void free_inf_file(struct inf_file *file)
Definition: parser.c:897
BOOL WINAPI SetupGetStringFieldA(PINFCONTEXT context, DWORD index, PSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1878
BOOL WINAPI SetupGetInfFileListA(IN PCSTR DirectoryPath OPTIONAL, IN DWORD InfStyle, IN OUT PSTR ReturnBuffer OPTIONAL, IN DWORD ReturnBufferSize OPTIONAL, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2279
BOOL WINAPI SetupGetLineByIndexA(HINF hinf, PCSTR section, DWORD index, INFCONTEXT *context)
Definition: parser.c:1522
static const WCHAR InfFileSpecification[]
Definition: parser.c:33
static const WCHAR * comment_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:887
static const WCHAR InfDirectory[]
Definition: parser.c:32
static int push_token(struct parser *parser, const WCHAR *pos)
Definition: parser.c:523
#define MAX_SECTION_NAME_LEN
Definition: parser.c:36
BOOL WINAPI SetupDiGetINFClassW(IN PCWSTR InfName, OUT LPGUID ClassGuid, OUT PWSTR ClassName, IN DWORD ClassNameSize, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2323
static struct line * find_line(struct inf_file *file, int section_index, const WCHAR *name)
Definition: parser.c:188
static const WCHAR * trailing_spaces_state(struct parser *parser, const WCHAR *pos)
Definition: parser.c:868
HINF WINAPI SetupOpenMasterInf(VOID)
Definition: parser.c:1385
BOOL WINAPI SetupFindNextMatchLineW(PINFCONTEXT context_in, PCWSTR key, PINFCONTEXT context_out)
Definition: parser.c:1701
BOOL WINAPI SetupGetLineTextW(PINFCONTEXT context, HINF hinf, PCWSTR section_name, PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required)
Definition: parser.c:1763
static const parser_state_func parser_funcs[NB_PARSER_STATES]
Definition: parser.c:125
static const WCHAR Cleanup[]
Definition: register.c:80
r parent
Definition: btrfs.c:3010
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
size_t total
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint index
Definition: glext.h:6031
GLenum GLenum dst
Definition: glext.h:6340
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
#define MAX_FIELD_LEN
Definition: infcore.c:18
parser_state
Definition: infcore.c:26
#define INF_STYLE_OLDNT
Definition: infsupp.h:39
#define INF_STYLE_WIN4
Definition: infsupp.h:43
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
const char * filename
Definition: ioapi.h:137
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
static size_t elem
Definition: string.c:69
struct section sections[2]
Definition: diskspace.c:792
static UINT PSTR DWORD UINT * need
Definition: parser.c:36
static HWND child
Definition: cursoricon.c:298
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlIsTextUnicode(_In_ CONST VOID *Buffer, _In_ INT Size, _Inout_opt_ INT *Flags)
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteN(_Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:107
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteSize(_Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:145
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define DWORD
Definition: nt_native.h:44
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696
#define LOCALE_SYSTEM_DEFAULT
#define UNICODE_NULL
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
static unsigned __int64 next
Definition: rand_nt.c:6
PVOID pBuffer
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
#define strcmpW(s1, s2)
Definition: unicode.h:44
#define strchrW(s, c)
Definition: unicode.h:40
#define strcmpiW(s1, s2)
Definition: unicode.h:45
#define tolowerW(n)
Definition: unicode.h:50
#define strlenW(s)
Definition: unicode.h:34
#define strrchrW(s, c)
Definition: unicode.h:41
#define strcatW(d, s)
Definition: unicode.h:36
#define isxdigitW(n)
Definition: unicode.h:57
#define isspaceW(n)
Definition: unicode.h:58
#define strtolW(s, e, b)
Definition: unicode.h:39
#define strcpyW(d, s)
Definition: unicode.h:35
#define err(...)
const WCHAR * str
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI UuidFromStringW(RPC_WSTR s, UUID *uuid)
Definition: rpcrt4_main.c:614
#define CP_UTF8
Definition: nls.h:20
static char utf8_bom[3]
Definition: file.c:108
#define ERROR_WRONG_INF_STYLE
Definition: setupapi.h:292
#define ERROR_BAD_SECTION_NAME_LINE
Definition: setupapi.h:289
#define ERROR_EXPECTED_SECTION_NAME
Definition: setupapi.h:288
#define DIRID_SRCPATH
Definition: setupapi.h:187
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:294
#define ERROR_CLASS_MISMATCH
Definition: setupapi.h:298
#define ERROR_SECTION_NAME_TOO_LONG
Definition: setupapi.h:290
_In_ DWORD _In_ DWORD ReturnBufferSize
Definition: setupapi.h:1898
#define ERROR_LINE_NOT_FOUND
Definition: setupapi.h:295
BOOL(* FIND_CALLBACK)(LPCWSTR SectionName, PVOID Context)
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
HINF Inf
Definition: infsupp.h:24
UINT Line
Definition: infsupp.h:27
HINF CurrentInf
Definition: infsupp.h:25
UINT Section
Definition: infsupp.h:26
Definition: http.c:7252
Definition: parser.c:44
const WCHAR * text
Definition: parser.c:45
Definition: fci.c:127
char name[1]
Definition: fci.c:135
Definition: inf.c:49
struct inf_file * next
Definition: parser.c:65
unsigned int nb_sections
Definition: parser.c:68
unsigned int alloc_sections
Definition: parser.c:69
unsigned int alloc_fields
Definition: parser.c:72
WCHAR * string_pos
Definition: parser.c:67
unsigned int nb_fields
Definition: parser.c:71
struct section ** sections
Definition: parser.c:70
WCHAR * filename
Definition: parser.c:75
struct field * fields
Definition: parser.c:73
int strings_section
Definition: parser.c:74
WCHAR * strings
Definition: parser.c:66
Definition: copy.c:22
Definition: parser.c:49
int first_field
Definition: parser.c:50
int nb_fields
Definition: parser.c:51
int key_field
Definition: parser.c:52
Definition: name.c:39
Definition: import.c:81
unsigned int line_pos
Definition: inffile.c:96
const WCHAR * start
Definition: parser.c:96
PINFCACHESECTION cur_section
Definition: inffile.c:94
int stack_pos
Definition: inffile.c:92
int cur_section
Definition: parser.c:103
struct line * line
Definition: parser.c:104
struct inf_file * file
Definition: parser.c:98
const CHAR * end
Definition: inffile.c:88
const WCHAR * end
Definition: parser.c:97
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
FILE * file
Definition: import.c:82
PINFCACHELINE line
Definition: inffile.c:95
unsigned int broken_line
Definition: parser.c:106
Definition: parser.c:56
const WCHAR * name
Definition: parser.c:57
unsigned int alloc_lines
Definition: parser.c:59
unsigned int nb_lines
Definition: parser.c:58
struct line lines[16]
Definition: parser.c:60
Definition: format.c:80
uint16_t * PWSTR
Definition: typedefs.h:56
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
#define IN
Definition: typedefs.h:39
#define OUT
Definition: typedefs.h:40
Definition: pdh_main.c:96
static const WCHAR classW[]
Definition: lex.c:40
int ret
_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_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
int codepage
Definition: win_iconv.c:156
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
int * PINT
Definition: windef.h:177
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
#define ERROR_INVALID_DATA
Definition: winerror.h:116
#define GetLocaleInfo
Definition: winnls.h:1242
#define LOCALE_ILANGUAGE
Definition: winnls.h:25
char TCHAR
Definition: xmlstorage.h:189
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193