/*
 * INF file parsing
 *
 * Copyright 2002 Alexandre Julliard for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "winternl.h"
#include "winerror.h"
#include "setupapi.h"
#include "setupapi_private.h"

#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

#define CONTROL_Z  '\x1a'
#define MAX_SECTION_NAME_LEN  255
#define MAX_FIELD_LEN         511  /* larger fields get silently truncated */
/* actual string limit is MAX_INF_STRING_LENGTH+1 (plus terminating null) under Windows */
#define MAX_STRING_LEN        (MAX_INF_STRING_LENGTH+1)

/* inf file structure definitions */

struct field
{
    const WCHAR *text;         /* field text */
};

struct line
{
    int first_field;           /* index of first field in field array */
    int nb_fields;             /* number of fields in line */
    int key_field;             /* index of field for key or -1 if no key */
};

struct section
{
    const WCHAR *name;         /* section name */
    unsigned int nb_lines;     /* number of used lines */
    unsigned int alloc_lines;  /* total number of allocated lines in array below */
    struct line  lines[16];    /* lines information (grown dynamically, 16 is initial size) */
};

struct inf_file
{
    struct inf_file *next;            /* next appended file */
    WCHAR           *strings;         /* buffer for string data (section names and field values) */
    WCHAR           *string_pos;      /* position of next available string in buffer */
    unsigned int     nb_sections;     /* number of used sections */
    unsigned int     alloc_sections;  /* total number of allocated section pointers */
    struct section **sections;        /* section pointers array */
    unsigned int     nb_fields;
    unsigned int     alloc_fields;
    struct field    *fields;
    int              strings_section; /* index of [Strings] section or -1 if none */
    WCHAR           *src_root;        /* source root directory */
};

/* parser definitions */

enum parser_state
{
    LINE_START,      /* at beginning of a line */
    SECTION_NAME,    /* parsing a section name */
    KEY_NAME,        /* parsing a key name */
    VALUE_NAME,      /* parsing a value name */
    EOL_BACKSLASH,   /* backslash at end of line */
    QUOTES,          /* inside quotes */
    LEADING_SPACES,  /* leading spaces */
    TRAILING_SPACES, /* trailing spaces */
    COMMENT,         /* inside a comment */
    NB_PARSER_STATES
};

struct parser
{
    const WCHAR      *start;        /* start position of item being parsed */
    const WCHAR      *end;          /* end of buffer */
    struct inf_file  *file;         /* file being built */
    enum parser_state state;        /* current parser state */
    enum parser_state stack[4];     /* state stack */
    int               stack_pos;    /* current pos in stack */

    int               cur_section;  /* index of section being parsed*/
    struct line      *line;         /* current line */
    unsigned int      line_pos;     /* current line position in file */
    unsigned int      error;        /* error code */
    unsigned int      token_len;    /* current token len */
    WCHAR token[MAX_FIELD_LEN+1];   /* current token */
};

typedef const WCHAR * (*parser_state_func)( struct parser *parser, const WCHAR *pos );

/* parser state machine functions */
static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos );
static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos );

static const parser_state_func parser_funcs[NB_PARSER_STATES] =
{
    line_start_state,      /* LINE_START */
    section_name_state,    /* SECTION_NAME */
    key_name_state,        /* KEY_NAME */
    value_name_state,      /* VALUE_NAME */
    eol_backslash_state,   /* EOL_BACKSLASH */
    quotes_state,          /* QUOTES */
    leading_spaces_state,  /* LEADING_SPACES */
    trailing_spaces_state, /* TRAILING_SPACES */
    comment_state          /* COMMENT */
};


/* Unicode string constants */
static const WCHAR Version[]    = {'V','e','r','s','i','o','n',0};
static const WCHAR Signature[]  = {'S','i','g','n','a','t','u','r','e',0};
static const WCHAR Chicago[]    = {'$','C','h','i','c','a','g','o','$',0};
static const WCHAR WindowsNT[]  = {'$','W','i','n','d','o','w','s',' ','N','T','$',0};
static const WCHAR Windows95[]  = {'$','W','i','n','d','o','w','s',' ','9','5','$',0};
static const WCHAR LayoutFile[] = {'L','a','y','o','u','t','F','i','l','e',0};

/* extend an array, allocating more memory if necessary */
static void *grow_array( void *array, unsigned int *count, size_t elem )
{
    void *new_array;
    unsigned int new_count = *count + *count / 2;
    if (new_count < 32) new_count = 32;

    if (array)
	new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );
    else
	new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );

    if (new_array)
        *count = new_count;
    else
	if (array)
    	    HeapFree( GetProcessHeap(), 0, array );
    return new_array;
}


/* find a section by name */
static int find_section( struct inf_file *file, const WCHAR *name )
{
    int i;

    for (i = 0; i < file->nb_sections; i++)
        if (!strcmpiW( name, file->sections[i]->name )) return i;
    return -1;
}


/* find a line by name */
static struct line *find_line( struct inf_file *file, int section_index, const WCHAR *name )
{
    struct section *section;
    struct line *line;
    int i;

    if (section_index < 0 || section_index >= file->nb_sections) return NULL;
    section = file->sections[section_index];
    for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
    {
        if (line->key_field == -1) continue;
        if (!strcmpiW( name, file->fields[line->key_field].text )) return line;
    }
    return NULL;
}


/* add a section to the file and return the section index */
static int add_section( struct inf_file *file, const WCHAR *name )
{
    struct section *section;

    if (file->nb_sections >= file->alloc_sections)
    {
        if (!(file->sections = grow_array( file->sections, &file->alloc_sections,
                                           sizeof(file->sections[0]) ))) return -1;
    }
    if (!(section = HeapAlloc( GetProcessHeap(), 0, sizeof(*section) ))) return -1;
    section->name        = name;
    section->nb_lines    = 0;
    section->alloc_lines = sizeof(section->lines)/sizeof(section->lines[0]);
    file->sections[file->nb_sections] = section;
    return file->nb_sections++;
}


/* add a line to a given section */
static struct line *add_line( struct inf_file *file, int section_index )
{
    struct section *section;
    struct line *line;

    assert( section_index >= 0 && section_index < file->nb_sections );

    section = file->sections[section_index];
    if (section->nb_lines == section->alloc_lines)  /* need to grow the section */
    {
        int size = sizeof(*section) - sizeof(section->lines) + 2*section->alloc_lines*sizeof(*line);
        if (!(section = HeapReAlloc( GetProcessHeap(), 0, section, size ))) return NULL;
        section->alloc_lines *= 2;
        file->sections[section_index] = section;
    }
    line = &section->lines[section->nb_lines++];
    line->first_field = file->nb_fields;
    line->nb_fields   = 0;
    line->key_field   = -1;
    return line;
}


/* retrieve a given line from section/line index */
inline static struct line *get_line( struct inf_file *file, unsigned int section_index,
                                     unsigned int line_index )
{
    struct section *section;

    if (section_index >= file->nb_sections) return NULL;
    section = file->sections[section_index];
    if (line_index >= section->nb_lines) return NULL;
    return &section->lines[line_index];
}


/* retrieve a given field from section/line/field index */
static struct field *get_field( struct inf_file *file, int section_index, int line_index,
                                int field_index )
{
    struct line *line = get_line( file, section_index, line_index );

    if (!line) return NULL;
    if (!field_index)  /* get the key */
    {
        if (line->key_field == -1) return NULL;
        return &file->fields[line->key_field];
    }
    field_index--;
    if (field_index >= line->nb_fields) return NULL;
    return &file->fields[line->first_field + field_index];
}


/* allocate a new field, growing the array if necessary */
static struct field *add_field( struct inf_file *file, const WCHAR *text )
{
    struct field *field;

    if (file->nb_fields >= file->alloc_fields)
    {
        if (!(file->fields = grow_array( file->fields, &file->alloc_fields,
                                         sizeof(file->fields[0]) ))) return NULL;
    }
    field = &file->fields[file->nb_fields++];
    field->text = text;
    return field;
}


/* retrieve the string substitution for a directory id */
static const WCHAR *get_dirid_subst( int dirid, unsigned int *len )
{
    extern const WCHAR *DIRID_get_string( HINF hinf, int dirid );
    const WCHAR *ret = DIRID_get_string( 0, dirid );
    if (ret) *len = strlenW(ret);
    return ret;
}


/* retrieve the string substitution for a given string, or NULL if not found */
/* if found, len is set to the substitution length */
static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, unsigned int *len )
{
    static const WCHAR percent = '%';

    struct section *strings_section;
    struct line *line;
    struct field *field;
    int i, dirid;
    WCHAR *dirid_str, *end;
    const WCHAR *ret = NULL;

    if (!*len)  /* empty string (%%) is replaced by single percent */
    {
        *len = 1;
        return &percent;
    }
    if (file->strings_section == -1) goto not_found;
    strings_section = file->sections[file->strings_section];
    for (i = 0, line = strings_section->lines; i < strings_section->nb_lines; i++, line++)
    {
        if (line->key_field == -1) continue;
        if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue;
        if (!file->fields[line->key_field].text[*len]) break;
    }
    if (i == strings_section->nb_lines || !line->nb_fields) goto not_found;
    field = &file->fields[line->first_field];
    *len = strlenW( field->text );
    return field->text;

 not_found:  /* check for integer id */
    if ((dirid_str = HeapAlloc( GetProcessHeap(), 0, (*len+1) * sizeof(WCHAR) )))
    {
        memcpy( dirid_str, str, *len * sizeof(WCHAR) );
        dirid_str[*len] = 0;
        dirid = strtolW( dirid_str, &end, 10 );
        if (!*end) ret = get_dirid_subst( dirid, len );
        HeapFree( GetProcessHeap(), 0, dirid_str );
        return ret;
    }
    return NULL;
}


/* do string substitutions on the specified text */
/* the buffer is assumed to be large enough */
/* returns necessary length not including terminating null */
unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCHAR *buffer,
                                   unsigned int size )
{
    const WCHAR *start, *subst, *p;
    unsigned int len, total = 0;
    int inside = 0;

    if (!buffer) size = MAX_STRING_LEN + 1;
    for (p = start = text; *p; p++)
    {
        if (*p != '%') continue;
        inside = !inside;
        if (inside)  /* start of a %xx% string */
        {
            len = p - start;
            if (len > size - 1) len = size - 1;
            if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
            total += len;
            size -= len;
            start = p;
        }
        else /* end of the %xx% string, find substitution */
        {
            len = p - start - 1;
            subst = get_string_subst( file, start + 1, &len );
            if (!subst)
            {
                subst = start;
                len = p - start + 1;
            }
            if (len > size - 1) len = size - 1;
            if (buffer) memcpy( buffer + total, subst, len * sizeof(WCHAR) );
            total += len;
            size -= len;
            start = p + 1;
        }
    }

    if (start != p) /* unfinished string, copy it */
    {
        len = p - start;
        if (len > size - 1) len = size - 1;
        if (buffer) memcpy( buffer + total, start, len * sizeof(WCHAR) );
        total += len;
    }
    if (buffer && size) buffer[total] = 0;
    return total;
}


/* do string substitutions on the specified text */
/* the buffer is assumed to be large enough */
/* returns necessary length not including terminating null */
unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text, char *buffer,
                                   unsigned int size )
{
    WCHAR buffW[MAX_STRING_LEN+1];
    DWORD ret;

    unsigned int len = PARSER_string_substW( file, text, buffW, sizeof(buffW)/sizeof(WCHAR) );
    if (!buffer) RtlUnicodeToMultiByteSize( &ret, buffW, len * sizeof(WCHAR) );
    else
    {
        RtlUnicodeToMultiByteN( buffer, size-1, &ret, buffW, len * sizeof(WCHAR) );
        buffer[ret] = 0;
    }
    return ret;
}


/* push some string data into the strings buffer */
static WCHAR *push_string( struct inf_file *file, const WCHAR *string )
{
    WCHAR *ret = file->string_pos;
    strcpyW( ret, string );
    file->string_pos += strlenW( ret ) + 1;
    return ret;
}


/* push the current state on the parser stack */
inline static void push_state( struct parser *parser, enum parser_state state )
{
    assert( parser->stack_pos < sizeof(parser->stack)/sizeof(parser->stack[0]) );
    parser->stack[parser->stack_pos++] = state;
}


/* pop the current state */
inline static void pop_state( struct parser *parser )
{
    assert( parser->stack_pos );
    parser->state = parser->stack[--parser->stack_pos];
}


/* set the parser state and return the previous one */
inline static enum parser_state set_state( struct parser *parser, enum parser_state state )
{
    enum parser_state ret = parser->state;
    parser->state = state;
    return ret;
}


/* check if the pointer points to an end of file */
inline static int is_eof( struct parser *parser, const WCHAR *ptr )
{
    return (ptr >= parser->end || *ptr == CONTROL_Z);
}


/* check if the pointer points to an end of line */
inline static int is_eol( struct parser *parser, const WCHAR *ptr )
{
    return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\n');
}


/* push data from current token start up to pos into the current token */
static int push_token( struct parser *parser, const WCHAR *pos )
{
    int len = pos - parser->start;
    const WCHAR *src = parser->start;
    WCHAR *dst = parser->token + parser->token_len;

    if (len > MAX_FIELD_LEN - parser->token_len) len = MAX_FIELD_LEN - parser->token_len;

    parser->token_len += len;
    for ( ; len > 0; len--, dst++, src++) *dst = *src ? *src : ' ';
    *dst = 0;
    parser->start = pos;
    return 0;
}


/* add a section with the current token as name */
static int add_section_from_token( struct parser *parser )
{
    int section_index;

    if (parser->token_len > MAX_SECTION_NAME_LEN)
    {
        parser->error = ERROR_SECTION_NAME_TOO_LONG;
        return -1;
    }
    if ((section_index = find_section( parser->file, parser->token )) == -1)
    {
        /* need to create a new one */
        const WCHAR *name = push_string( parser->file, parser->token );
        if ((section_index = add_section( parser->file, name )) == -1)
        {
            parser->error = ERROR_NOT_ENOUGH_MEMORY;
            return -1;
        }
    }
    parser->token_len = 0;
    parser->cur_section = section_index;
    return section_index;
}


/* add a field containing the current token to the current line */
static struct field *add_field_from_token( struct parser *parser, int is_key )
{
    struct field *field;
    WCHAR *text;

    if (!parser->line)  /* need to start a new line */
    {
        if (parser->cur_section == -1)  /* got a line before the first section */
        {
            parser->error = ERROR_WRONG_INF_STYLE;
            return NULL;
        }
        if (!(parser->line = add_line( parser->file, parser->cur_section ))) goto error;
    }
    else assert(!is_key);

    text = push_string( parser->file, parser->token );
    if ((field = add_field( parser->file, text )))
    {
        if (!is_key) parser->line->nb_fields++;
        else
        {
            /* replace first field by key field */
            parser->line->key_field = parser->line->first_field;
            parser->line->first_field++;
        }
        parser->token_len = 0;
        return field;
    }
 error:
    parser->error = ERROR_NOT_ENOUGH_MEMORY;
    return NULL;
}


/* close the current line and prepare for parsing a new one */
static void close_current_line( struct parser *parser )
{
    struct line *cur_line = parser->line;

    if (cur_line)
    {
        /* if line has a single field and no key, the field is the key too */
        if (cur_line->nb_fields == 1 && cur_line->key_field == -1)
            cur_line->key_field = cur_line->first_field;
    }
    parser->line = NULL;
}


/* handler for parser LINE_START state */
static const WCHAR *line_start_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p;

    for (p = pos; !is_eof( parser, p ); p++)
    {
        switch(*p)
        {
        case '\n':
            parser->line_pos++;
            close_current_line( parser );
            break;
        case ';':
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );
            return p + 1;
        case '[':
            parser->start = p + 1;
            set_state( parser, SECTION_NAME );
            return p + 1;
        default:
            if (!isspaceW(*p))
            {
                parser->start = p;
                set_state( parser, KEY_NAME );
                return p;
            }
            break;
        }
    }
    close_current_line( parser );
    return NULL;
}


/* handler for parser SECTION_NAME state */
static const WCHAR *section_name_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == ']')
        {
            push_token( parser, p );
            if (add_section_from_token( parser ) == -1) return NULL;
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );  /* ignore everything else on the line */
            return p + 1;
        }
    }
    parser->error = ERROR_BAD_SECTION_NAME_LINE; /* unfinished section name */
    return NULL;
}


/* handler for parser KEY_NAME state */
static const WCHAR *key_name_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p, *token_end = parser->start;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == ',') break;
        switch(*p)
        {

         case '=':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 1 )) return NULL;
            parser->start = p + 1;
            push_state( parser, VALUE_NAME );
            set_state( parser, LEADING_SPACES );
            return p + 1;
        case ';':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 0 )) return NULL;
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );
            return p + 1;
        case '"':
            push_token( parser, token_end );
            parser->start = p + 1;
            push_state( parser, KEY_NAME );
            set_state( parser, QUOTES );
            return p + 1;
        case '\\':
            push_token( parser, token_end );
            parser->start = p;
            push_state( parser, KEY_NAME );
            set_state( parser, EOL_BACKSLASH );
            return p;
        default:
            if (!isspaceW(*p)) token_end = p + 1;
            else
            {
                push_token( parser, p );
                push_state( parser, KEY_NAME );
                set_state( parser, TRAILING_SPACES );
                return p;
            }
            break;
        }
    }
    push_token( parser, token_end );
    set_state( parser, VALUE_NAME );
    return p;
}


/* handler for parser VALUE_NAME state */
static const WCHAR *value_name_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p, *token_end = parser->start;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        switch(*p)
        {
        case ';':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 0 )) return NULL;
            push_state( parser, LINE_START );
            set_state( parser, COMMENT );
            return p + 1;
        case ',':
            push_token( parser, token_end );
            if (!add_field_from_token( parser, 0 )) return NULL;
            parser->start = p + 1;
            push_state( parser, VALUE_NAME );
            set_state( parser, LEADING_SPACES );
            return p + 1;
        case '"':
            push_token( parser, token_end );
            parser->start = p + 1;
            push_state( parser, VALUE_NAME );
            set_state( parser, QUOTES );
            return p + 1;
        case '\\':
            push_token( parser, token_end );
            parser->start = p;
            push_state( parser, VALUE_NAME );
            set_state( parser, EOL_BACKSLASH );
            return p;
        default:
            if (!isspaceW(*p)) token_end = p + 1;
            else
            {
                push_token( parser, p );
                push_state( parser, VALUE_NAME );
                set_state( parser, TRAILING_SPACES );
                return p;
            }
            break;
        }
    }
    push_token( parser, token_end );
    if (!add_field_from_token( parser, 0 )) return NULL;
    set_state( parser, LINE_START );
    return p;
}


/* handler for parser EOL_BACKSLASH state */
static const WCHAR *eol_backslash_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p;

    for (p = pos; !is_eof( parser, p ); p++)
    {
        switch(*p)
        {
        case '\n':
            parser->line_pos++;
            parser->start = p + 1;
            set_state( parser, LEADING_SPACES );
            return p + 1;
        case '\\':
            continue;
        case ';':
            push_state( parser, EOL_BACKSLASH );
            set_state( parser, COMMENT );
            return p + 1;
        default:
            if (isspaceW(*p)) continue;
            push_token( parser, p );
            pop_state( parser );
            return p;
        }
    }
    parser->start = p;
    pop_state( parser );
    return p;
}


/* handler for parser QUOTES state */
static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p, *token_end = parser->start;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == '"')
        {
            if (p+1 < parser->end && p[1] == '"')  /* double quotes */
            {
                push_token( parser, p + 1 );
                parser->start = token_end = p + 2;
                p++;
            }
            else  /* end of quotes */
            {
                push_token( parser, p );
                parser->start = p + 1;
                pop_state( parser );
                return p + 1;
            }
        }
    }
    push_token( parser, p );
    pop_state( parser );
    return p;
}


/* handler for parser LEADING_SPACES state */
static const WCHAR *leading_spaces_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == '\\')
        {
            parser->start = p;
            set_state( parser, EOL_BACKSLASH );
            return p;
        }
        if (!isspaceW(*p)) break;
    }
    parser->start = p;
    pop_state( parser );
    return p;
}


/* handler for parser TRAILING_SPACES state */
static const WCHAR *trailing_spaces_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p;

    for (p = pos; !is_eol( parser, p ); p++)
    {
        if (*p == '\\')
        {
            set_state( parser, EOL_BACKSLASH );
            return p;
        }
        if (!isspaceW(*p)) break;
    }
    pop_state( parser );
    return p;
}


/* handler for parser COMMENT state */
static const WCHAR *comment_state( struct parser *parser, const WCHAR *pos )
{
    const WCHAR *p = pos;

    while (!is_eol( parser, p )) p++;
    pop_state( parser );
    return p;
}


/* parse a complete buffer */
static DWORD parse_buffer( struct inf_file *file, const WCHAR *buffer, const WCHAR *end,
                           UINT *error_line )
{
    static const WCHAR Strings[] = {'S','t','r','i','n','g','s',0};

    struct parser parser;
    const WCHAR *pos = buffer;

    parser.start       = buffer;
    parser.end         = end;
    parser.file        = file;
    parser.line        = NULL;
    parser.state       = LINE_START;
    parser.stack_pos   = 0;
    parser.cur_section = -1;
    parser.line_pos    = 1;
    parser.error       = 0;
    parser.token_len   = 0;

    /* parser main loop */
    while (pos) pos = (parser_funcs[parser.state])( &parser, pos );

    /* trim excess buffer space */
    if (file->alloc_sections > file->nb_sections)
    {
        file->sections = HeapReAlloc( GetProcessHeap(), 0, file->sections,
                                      file->nb_sections * sizeof(file->sections[0]) );
        file->alloc_sections = file->nb_sections;
    }
    if (file->alloc_fields > file->nb_fields)
    {
        file->fields = HeapReAlloc( GetProcessHeap(), 0, file->fields,
                                    file->nb_fields * sizeof(file->fields[0]) );
        file->alloc_fields = file->nb_fields;
    }
    file->strings = HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, file->strings,
                                 (file->string_pos - file->strings) * sizeof(WCHAR) );

    if (parser.error)
    {
        if (error_line) *error_line = parser.line_pos;
        return parser.error;
    }

    /* find the [strings] section */
    file->strings_section = find_section( file, Strings );
    return 0;
}


/* append a child INF file to its parent list, in a thread-safe manner */
static void append_inf_file( struct inf_file *parent, struct inf_file *child )
{
    struct inf_file **ppnext = &parent->next;
    child->next = NULL;

    for (;;)
    {
        struct inf_file *next = InterlockedCompareExchangePointer( (void **)ppnext, child, NULL );
        if (!next) return;
        ppnext = &next->next;
    }
}


/***********************************************************************
 *            parse_file
 *
 * parse an INF file.
 */
static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *error_line )
{
    void *buffer;
    DWORD err = 0;
    struct inf_file *file;

    DWORD size = GetFileSize( handle, NULL );
    HANDLE mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, size, NULL );
    if (!mapping) return NULL;
    buffer = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, size );
    NtClose( mapping );
    if (!buffer) return NULL;

    if (class) FIXME( "class %s not supported yet\n", debugstr_w(class) );

    if (!(file = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*file) )))
    {
        err = ERROR_NOT_ENOUGH_MEMORY;
        goto done;
    }

    /* we won't need more strings space than the size of the file,
     * so we can preallocate it here
     */
    if (!(file->strings = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) )))
    {
        err = ERROR_NOT_ENOUGH_MEMORY;
        goto done;
    }
    file->string_pos = file->strings;
    file->strings_section = -1;

    if (!RtlIsTextUnicode( buffer, size, NULL ))
    {
        WCHAR *new_buff = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
        if (new_buff)
        {
            DWORD len = MultiByteToWideChar( CP_ACP, 0, buffer, size, new_buff,
                                             size * sizeof(WCHAR) );
            err = parse_buffer( file, new_buff, new_buff + len, error_line );
            HeapFree( GetProcessHeap(), 0, new_buff );
        }
    }
    else err = parse_buffer( file, buffer, (WCHAR *)((char *)buffer + size), error_line );

    if (!err)  /* now check signature */
    {
        int version_index = find_section( file, Version );
        if (version_index != -1)
        {
            struct line *line = find_line( file, version_index, Signature );
            if (line && line->nb_fields > 0)
            {
                struct field *field = file->fields + line->first_field;
                if (!strcmpiW( field->text, Chicago )) goto done;
                if (!strcmpiW( field->text, WindowsNT )) goto done;
                if (!strcmpiW( field->text, Windows95 )) goto done;
            }
        }
        err = ERROR_WRONG_INF_STYLE;
    }

 done:
    UnmapViewOfFile( buffer );
    if (err)
    {
        HeapFree( GetProcessHeap(), 0, file );
        SetLastError( err );
        file = NULL;
    }
    return file;
}


/***********************************************************************
 *            PARSER_get_src_root
 *
 * Retrieve the source directory of an inf file.
 */
const WCHAR *PARSER_get_src_root( HINF hinf )
{
    struct inf_file *file = hinf;
    return file->src_root;
}


/***********************************************************************
 *            PARSER_get_dest_dir
 *
 * retrieve a destination dir of the form "dirid,relative_path" in the given entry.
 * returned buffer must be freed by caller.
 */
WCHAR *PARSER_get_dest_dir( INFCONTEXT *context )
{
    const WCHAR *dir;
    WCHAR *ptr, *ret;
    INT dirid;
    DWORD len1, len2;

    if (!SetupGetIntField( context, 1, &dirid )) return NULL;
    if (!(dir = DIRID_get_string( context->Inf, dirid ))) return NULL;
    len1 = strlenW(dir) + 1;
    if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0;
    if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2) * sizeof(WCHAR) ))) return NULL;
    strcpyW( ret, dir );
    ptr = ret + strlenW(ret);
    if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\';
    if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0;
    return ret;
}


/***********************************************************************
 *            SetupOpenInfFileA   (SETUPAPI.@)
 */
HINF WINAPI SetupOpenInfFileA( PCSTR name, PCSTR class, DWORD style, UINT *error )
{
    UNICODE_STRING nameW, classW;
    HINF ret = (HINF)INVALID_HANDLE_VALUE;

    classW.Buffer = NULL;
    if (class && !RtlCreateUnicodeStringFromAsciiz( &classW, class ))
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return ret;
    }
    if (RtlCreateUnicodeStringFromAsciiz( &nameW, name ))
    {
        ret = SetupOpenInfFileW( nameW.Buffer, classW.Buffer, style, error );
        RtlFreeUnicodeString( &nameW );
    }
    RtlFreeUnicodeString( &classW );
    return ret;
}


/***********************************************************************
 *            SetupOpenInfFileW   (SETUPAPI.@)
 */
HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *error )
{
    struct inf_file *file = NULL;
    HANDLE handle;
    WCHAR *path, *p;
    UINT len;

    if (strchrW( name, '\\' ) || strchrW( name, '/' ))
    {
        if (!(len = GetFullPathNameW( name, 0, NULL, NULL ))) return (HINF)INVALID_HANDLE_VALUE;
        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
        {
            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
            return (HINF)INVALID_HANDLE_VALUE;
        }
        GetFullPathNameW( name, len, path, NULL );
        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
    }
    else  /* try Windows directory */
    {
        static const WCHAR Inf[]      = {'\\','i','n','f','\\',0};
        static const WCHAR System32[] = {'\\','s','y','s','t','e','m','3','2','\\',0};

        len = GetWindowsDirectoryW( NULL, 0 ) + strlenW(name) + 12;
        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
        {
            SetLastError( ERROR_NOT_ENOUGH_MEMORY );
            return (HINF)INVALID_HANDLE_VALUE;
        }
        GetWindowsDirectoryW( path, len );
        p = path + strlenW(path);
        strcpyW( p, Inf );
        strcatW( p, name );
        handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
        if (handle == INVALID_HANDLE_VALUE)
        {
            strcpyW( p, System32 );
            strcatW( p, name );
            handle = CreateFileW( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
        }
    }

    if (handle != INVALID_HANDLE_VALUE)
    {
        file = parse_file( handle, class, error );
        CloseHandle( handle );
    }
    if (!file)
    {
        HeapFree( GetProcessHeap(), 0, path );
        return (HINF)INVALID_HANDLE_VALUE;
    }
    TRACE( "%s -> %p\n", debugstr_w(path), file );
    file->src_root = path;
    if ((p = strrchrW( path, '\\' ))) p[1] = 0;  /* remove file name */
    SetLastError( 0 );
    return (HINF)file;
}


/***********************************************************************
 *            SetupOpenAppendInfFileA    (SETUPAPI.@)
 */
BOOL WINAPI SetupOpenAppendInfFileA( PCSTR name, HINF parent_hinf, UINT *error )
{
    HINF child_hinf;

    if (!name) return SetupOpenAppendInfFileW( NULL, parent_hinf, error );
    child_hinf = SetupOpenInfFileA( name, NULL, INF_STYLE_WIN4, error );
    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
    append_inf_file( parent_hinf, child_hinf );
    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_a(name), child_hinf );
    return TRUE;
}


/***********************************************************************
 *            SetupOpenAppendInfFileW    (SETUPAPI.@)
 */
BOOL WINAPI SetupOpenAppendInfFileW( PCWSTR name, HINF parent_hinf, UINT *error )
{
    HINF child_hinf;

    if (!name)
    {
        INFCONTEXT context;
        WCHAR filename[MAX_PATH];
        int idx = 1;

        if (!SetupFindFirstLineW( parent_hinf, Version, LayoutFile, &context )) return FALSE;
        while (SetupGetStringFieldW( &context, idx++, filename,
                                     sizeof(filename)/sizeof(WCHAR), NULL ))
        {
            child_hinf = SetupOpenInfFileW( filename, NULL, INF_STYLE_WIN4, error );
            if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
            append_inf_file( parent_hinf, child_hinf );
            TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(filename), child_hinf );
        }
        return TRUE;
    }
    child_hinf = SetupOpenInfFileW( name, NULL, INF_STYLE_WIN4, error );
    if (child_hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE;
    append_inf_file( parent_hinf, child_hinf );
    TRACE( "%p: appended %s (%p)\n", parent_hinf, debugstr_w(name), child_hinf );
    return TRUE;
}


/***********************************************************************
 *            SetupCloseInfFile   (SETUPAPI.@)
 */
void WINAPI SetupCloseInfFile( HINF hinf )
{
    struct inf_file *file = hinf;
    int i;

    for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
    HeapFree( GetProcessHeap(), 0, file->src_root );
    HeapFree( GetProcessHeap(), 0, file->sections );
    HeapFree( GetProcessHeap(), 0, file->fields );
    HeapFree( GetProcessHeap(), 0, file->strings );
    HeapFree( GetProcessHeap(), 0, file );
}


/***********************************************************************
 *            SetupGetLineCountA   (SETUPAPI.@)
 */
LONG WINAPI SetupGetLineCountA( HINF hinf, PCSTR name )
{
    UNICODE_STRING sectionW;
    LONG ret = -1;

    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, name ))
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
    else
    {
        ret = SetupGetLineCountW( hinf, sectionW.Buffer );
        RtlFreeUnicodeString( &sectionW );
    }
    return ret;
}


/***********************************************************************
 *            SetupGetLineCountW   (SETUPAPI.@)
 */
LONG WINAPI SetupGetLineCountW( HINF hinf, PCWSTR section )
{
    struct inf_file *file = hinf;
    int section_index;
    LONG ret = -1;

    for (file = hinf; file; file = file->next)
    {
        if ((section_index = find_section( file, section )) == -1) continue;
        if (ret == -1) ret = 0;
        ret += file->sections[section_index]->nb_lines;
    }
    TRACE( "(%p,%s) returning %ld\n", hinf, debugstr_w(section), ret );
    SetLastError( (ret == -1) ? ERROR_SECTION_NOT_FOUND : 0 );
    return ret;
}


/***********************************************************************
 *            SetupGetLineByIndexA   (SETUPAPI.@)
 */
BOOL WINAPI SetupGetLineByIndexA( HINF hinf, PCSTR section, DWORD index, INFCONTEXT *context )
{
    UNICODE_STRING sectionW;
    BOOL ret = FALSE;

    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
    else
    {
        ret = SetupGetLineByIndexW( hinf, sectionW.Buffer, index, context );
        RtlFreeUnicodeString( &sectionW );
    }
    return ret;
}


/***********************************************************************
 *            SetupGetLineByIndexW   (SETUPAPI.@)
 */
BOOL WINAPI SetupGetLineByIndexW( HINF hinf, PCWSTR section, DWORD index, INFCONTEXT *context )
{
    struct inf_file *file = hinf;
    int section_index;

    SetLastError( ERROR_SECTION_NOT_FOUND );
    for (file = hinf; file; file = file->next)
    {
        if ((section_index = find_section( file, section )) == -1) continue;
        SetLastError( ERROR_LINE_NOT_FOUND );
        if (index < file->sections[section_index]->nb_lines)
        {
            context->Inf        = hinf;
            context->CurrentInf = file;
            context->Section    = section_index;
            context->Line       = index;
            SetLastError( 0 );
            TRACE( "(%p,%s): returning %d/%ld\n",
                   hinf, debugstr_w(section), section_index, index );
            return TRUE;
        }
        index -= file->sections[section_index]->nb_lines;
    }
    TRACE( "(%p,%s) not found\n", hinf, debugstr_w(section) );
    return FALSE;
}


/***********************************************************************
 *            SetupFindFirstLineA   (SETUPAPI.@)
 */
BOOL WINAPI SetupFindFirstLineA( HINF hinf, PCSTR section, PCSTR key, INFCONTEXT *context )
{
    UNICODE_STRING sectionW, keyW;
    BOOL ret = FALSE;

    if (!RtlCreateUnicodeStringFromAsciiz( &sectionW, section ))
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return FALSE;
    }

    if (!key) ret = SetupFindFirstLineW( hinf, sectionW.Buffer, NULL, context );
    else
    {
        if (RtlCreateUnicodeStringFromAsciiz( &keyW, key ))
        {
            ret = SetupFindFirstLineW( hinf, sectionW.Buffer, keyW.Buffer, context );
            RtlFreeUnicodeString( &keyW );
        }
        else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
    }
    RtlFreeUnicodeString( &sectionW );
    return ret;
}


/***********************************************************************
 *            SetupFindFirstLineW   (SETUPAPI.@)
 */
BOOL WINAPI SetupFindFirstLineW( HINF hinf, PCWSTR section, PCWSTR key, INFCONTEXT *context )
{
    struct inf_file *file;
    int section_index;

    SetLastError( ERROR_SECTION_NOT_FOUND );
    for (file = hinf; file; file = file->next)
    {
        if ((section_index = find_section( file, section )) == -1) continue;
        if (key)
        {
            INFCONTEXT ctx;
            ctx.Inf        = hinf;
            ctx.CurrentInf = file;
            ctx.Section    = section_index;
            ctx.Line       = -1;
            return SetupFindNextMatchLineW( &ctx, key, context );
        }
        SetLastError( ERROR_LINE_NOT_FOUND );  /* found at least one section */
        if (file->sections[section_index]->nb_lines)
        {
            context->Inf        = hinf;
            context->CurrentInf = file;
            context->Section    = section_index;
            context->Line       = 0;
            SetLastError( 0 );
            TRACE( "(%p,%s,%s): returning %d/0\n",
                   hinf, debugstr_w(section), debugstr_w(key), section_index );
            return TRUE;
        }
    }
    TRACE( "(%p,%s,%s): not found\n", hinf, debugstr_w(section), debugstr_w(key) );
    return FALSE;
}


/***********************************************************************
 *            SetupFindNextLine   (SETUPAPI.@)
 */
BOOL WINAPI SetupFindNextLine( PINFCONTEXT context_in, PINFCONTEXT context_out )
{
    struct inf_file *file = context_in->CurrentInf;
    struct section *section;

    if (context_in->Section >= file->nb_sections) goto error;

    section = file->sections[context_in->Section];
    if (context_in->Line+1 < section->nb_lines)
    {
        if (context_out != context_in) *context_out = *context_in;
        context_out->Line++;
        SetLastError( 0 );
        return TRUE;
    }

    /* now search the appended files */

    for (file = file->next; file; file = file->next)
    {
        int section_index = find_section( file, section->name );
        if (section_index == -1) continue;
        if (file->sections[section_index]->nb_lines)
        {
            context_out->Inf        = context_in->Inf;
            context_out->CurrentInf = file;
            context_out->Section    = section_index;
            context_out->Line       = 0;
            SetLastError( 0 );
            return TRUE;
        }
    }
 error:
    SetLastError( ERROR_LINE_NOT_FOUND );
    return FALSE;
}


/***********************************************************************
 *            SetupFindNextMatchLineA   (SETUPAPI.@)
 */
BOOL WINAPI SetupFindNextMatchLineA( PINFCONTEXT context_in, PCSTR key,
                                     PINFCONTEXT context_out )
{
    UNICODE_STRING keyW;
    BOOL ret = FALSE;

    if (!key) return SetupFindNextLine( context_in, context_out );

    if (!RtlCreateUnicodeStringFromAsciiz( &keyW, key ))
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
    else
    {
        ret = SetupFindNextMatchLineW( context_in, keyW.Buffer, context_out );
        RtlFreeUnicodeString( &keyW );
    }
    return ret;
}


/***********************************************************************
 *            SetupFindNextMatchLineW   (SETUPAPI.@)
 */
BOOL WINAPI SetupFindNextMatchLineW( PINFCONTEXT context_in, PCWSTR key,
                                     PINFCONTEXT context_out )
{
    struct inf_file *file = context_in->CurrentInf;
    struct section *section;
    struct line *line;
    unsigned int i;

    if (!key) return SetupFindNextLine( context_in, context_out );

    if (context_in->Section >= file->nb_sections) goto error;

    section = file->sections[context_in->Section];

    for (i = context_in->Line+1, line = &section->lines[i]; i < section->nb_lines; i++, line++)
    {
        if (line->key_field == -1) continue;
        if (!strcmpiW( key, file->fields[line->key_field].text ))
        {
            if (context_out != context_in) *context_out = *context_in;
            context_out->Line = i;
            SetLastError( 0 );
            TRACE( "(%p,%s,%s): returning %d\n",
                   file, debugstr_w(section->name), debugstr_w(key), i );
            return TRUE;
        }
    }

    /* now search the appended files */

    for (file = file->next; file; file = file->next)
    {
        int section_index = find_section( file, section->name );
        if (section_index == -1) continue;
        section = file->sections[section_index];
        for (i = 0, line = section->lines; i < section->nb_lines; i++, line++)
        {
            if (line->key_field == -1) continue;
            if (!strcmpiW( key, file->fields[line->key_field].text ))
            {
                context_out->Inf        = context_in->Inf;
                context_out->CurrentInf = file;
                context_out->Section    = section_index;
                context_out->Line       = i;
                SetLastError( 0 );
                TRACE( "(%p,%s,%s): returning %d/%d\n",
                       file, debugstr_w(section->name), debugstr_w(key), section_index, i );
                return TRUE;
            }
        }
    }
    TRACE( "(%p,%s,%s): not found\n",
           context_in->CurrentInf, debugstr_w(section->name), debugstr_w(key) );
 error:
    SetLastError( ERROR_LINE_NOT_FOUND );
    return FALSE;
}


/***********************************************************************
 *		SetupGetLineTextW    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetLineTextW( PINFCONTEXT context, HINF hinf, PCWSTR section_name,
                               PCWSTR key_name, PWSTR buffer, DWORD size, PDWORD required )
{
    struct inf_file *file;
    struct line *line;
    struct field *field;
    int i;
    DWORD total = 0;

    if (!context)
    {
        INFCONTEXT new_context;
        if (!SetupFindFirstLineW( hinf, section_name, key_name, &new_context )) return FALSE;
        file = new_context.CurrentInf;
        line = get_line( file, new_context.Section, new_context.Line );
    }
    else
    {
        file = context->CurrentInf;
        if (!(line = get_line( file, context->Section, context->Line )))
        {
            SetLastError( ERROR_LINE_NOT_FOUND );
            return FALSE;
        }
    }

    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
        total += PARSER_string_substW( file, field->text, NULL, 0 ) + 1;

    if (required) *required = total;
    if (buffer)
    {
        if (total > size)
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
        {
            unsigned int len = PARSER_string_substW( file, field->text, buffer, size );
            if (i+1 < line->nb_fields) buffer[len] = ',';
            buffer += len + 1;
        }
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetLineTextA    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetLineTextA( PINFCONTEXT context, HINF hinf, PCSTR section_name,
                               PCSTR key_name, PSTR buffer, DWORD size, PDWORD required )
{
    struct inf_file *file;
    struct line *line;
    struct field *field;
    int i;
    DWORD total = 0;

    if (!context)
    {
        INFCONTEXT new_context;
        if (!SetupFindFirstLineA( hinf, section_name, key_name, &new_context )) return FALSE;
        file = new_context.CurrentInf;
        line = get_line( file, new_context.Section, new_context.Line );
    }
    else
    {
        file = context->CurrentInf;
        if (!(line = get_line( file, context->Section, context->Line )))
        {
            SetLastError( ERROR_LINE_NOT_FOUND );
            return FALSE;
        }
    }

    for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
        total += PARSER_string_substA( file, field->text, NULL, 0 ) + 1;

    if (required) *required = total;
    if (buffer)
    {
        if (total > size)
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
        for (i = 0, field = &file->fields[line->first_field]; i < line->nb_fields; i++, field++)
        {
            unsigned int len = PARSER_string_substA( file, field->text, buffer, size );
            if (i+1 < line->nb_fields) buffer[len] = ',';
            buffer += len + 1;
        }
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetFieldCount    (SETUPAPI.@)
 */
DWORD WINAPI SetupGetFieldCount( PINFCONTEXT context )
{
    struct inf_file *file = context->CurrentInf;
    struct line *line = get_line( file, context->Section, context->Line );

    if (!line) return 0;
    return line->nb_fields;
}


/***********************************************************************
 *		SetupGetStringFieldA    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetStringFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,
                                  DWORD size, PDWORD required )
{
    struct inf_file *file = context->CurrentInf;
    struct field *field = get_field( file, context->Section, context->Line, index );
    unsigned int len;

    SetLastError(0);
    if (!field) return FALSE;
    len = PARSER_string_substA( file, field->text, NULL, 0 );
    if (required) *required = len + 1;
    if (buffer)
    {
        if (size <= len)
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
        PARSER_string_substA( file, field->text, buffer, size );

        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",
               context->Inf, context->CurrentInf, context->Section, context->Line,
               index, debugstr_a(buffer) );
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetStringFieldW    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetStringFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,
                                  DWORD size, PDWORD required )
{
    struct inf_file *file = context->CurrentInf;
    struct field *field = get_field( file, context->Section, context->Line, index );
    unsigned int len;

    SetLastError(0);
    if (!field) return FALSE;
    len = PARSER_string_substW( file, field->text, NULL, 0 );
    if (required) *required = len + 1;
    if (buffer)
    {
        if (size <= len)
        {
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            return FALSE;
        }
        PARSER_string_substW( file, field->text, buffer, size );

        TRACE( "context %p/%p/%d/%d index %ld returning %s\n",
               context->Inf, context->CurrentInf, context->Section, context->Line,
               index, debugstr_w(buffer) );
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetIntField    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetIntField( PINFCONTEXT context, DWORD index, PINT result )
{
    char localbuff[20];
    char *end, *buffer = localbuff;
    DWORD required;
    INT res;
    BOOL ret = FALSE;

    if (!SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required ))
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE;
        if (!SetupGetStringFieldA( context, index, buffer, required, NULL )) goto done;
    }
    res = strtol( buffer, &end, 0 );
    if (end != buffer && !*end)
    {
        *result = res;
        ret = TRUE;
    }
    else SetLastError( ERROR_INVALID_DATA );

 done:
    if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer );
    return ret;
}


/***********************************************************************
 *		SetupGetBinaryField    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetBinaryField( PINFCONTEXT context, DWORD index, BYTE *buffer,
                                 DWORD size, LPDWORD required )
{
    struct inf_file *file = context->CurrentInf;
    struct line *line = get_line( file, context->Section, context->Line );
    struct field *field;
    int i;

    if (!line)
    {
        SetLastError( ERROR_LINE_NOT_FOUND );
        return FALSE;
    }
    if (!index || index >= line->nb_fields)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    index--;  /* fields start at 0 */
    if (required) *required = line->nb_fields - index;
    if (!buffer) return TRUE;
    if (size < line->nb_fields - index)
    {
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
        return FALSE;
    }
    field = &file->fields[line->first_field + index];
    for (i = index; i < line->nb_fields; i++, field++)
    {
        const WCHAR *p;
        DWORD value = 0;
        for (p = field->text; *p && isxdigitW(*p); p++)
        {
            if ((value <<= 4) > 255)
            {
                SetLastError( ERROR_INVALID_DATA );
                return FALSE;
            }
            if (*p <= '9') value |= (*p - '0');
            else value |= (tolowerW(*p) - 'a' + 10);
        }
        buffer[i - index] = value;
    }
    if (TRACE_ON(setupapi))
    {
        TRACE( "%p/%p/%d/%d index %ld returning",
               context->Inf, context->CurrentInf, context->Section, context->Line, index );
        for (i = index; i < line->nb_fields; i++) TRACE( " %02x", buffer[i - index] );
        TRACE( "\n" );
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetMultiSzFieldA    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetMultiSzFieldA( PINFCONTEXT context, DWORD index, PSTR buffer,
                                   DWORD size, LPDWORD required )
{
    struct inf_file *file = context->CurrentInf;
    struct line *line = get_line( file, context->Section, context->Line );
    struct field *field;
    unsigned int len;
    int i;
    DWORD total = 1;

    if (!line)
    {
        SetLastError( ERROR_LINE_NOT_FOUND );
        return FALSE;
    }
    if (!index || index >= line->nb_fields)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    index--;  /* fields start at 0 */
    field = &file->fields[line->first_field + index];
    for (i = index; i < line->nb_fields; i++, field++)
    {
        if (!(len = PARSER_string_substA( file, field->text, NULL, 0 ))) break;
        total += len + 1;
    }

    if (required) *required = total;
    if (!buffer) return TRUE;
    if (total > size)
    {
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
        return FALSE;
    }
    field = &file->fields[line->first_field + index];
    for (i = index; i < line->nb_fields; i++, field++)
    {
        if (!(len = PARSER_string_substA( file, field->text, buffer, size ))) break;
        buffer += len + 1;
    }
    *buffer = 0;  /* add final null */
    return TRUE;
}


/***********************************************************************
 *		SetupGetMultiSzFieldW    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetMultiSzFieldW( PINFCONTEXT context, DWORD index, PWSTR buffer,
                                   DWORD size, LPDWORD required )
{
    struct inf_file *file = context->CurrentInf;
    struct line *line = get_line( file, context->Section, context->Line );
    struct field *field;
    unsigned int len;
    int i;
    DWORD total = 1;

    if (!line)
    {
        SetLastError( ERROR_LINE_NOT_FOUND );
        return FALSE;
    }
    if (!index || index >= line->nb_fields)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
    index--;  /* fields start at 0 */
    field = &file->fields[line->first_field + index];
    for (i = index; i < line->nb_fields; i++, field++)
    {
        if (!(len = PARSER_string_substW( file, field->text, NULL, 0 ))) break;
        total += len + 1;
    }

    if (required) *required = total;
    if (!buffer) return TRUE;
    if (total > size)
    {
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
        return FALSE;
    }
    field = &file->fields[line->first_field + index];
    for (i = index; i < line->nb_fields; i++, field++)
    {
        if (!(len = PARSER_string_substW( file, field->text, buffer, size ))) break;
        buffer += len + 1;
    }
    *buffer = 0;  /* add final null */
    return TRUE;
}
