/*
 * 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 <assert.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>

#include "windef.h"
#include "ntddk.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/unicode.h"
#include "setupapi.h"
#include "setupx16.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 ((new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem )))
        *count = new_count;
    else
        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 = wcstol( 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;
}


/* 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++;
            parser->line = NULL;  /* start a new line */
            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;
        }
    }
    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;
}


/***********************************************************************
 *            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( const INFCONTEXT *context_in, INFCONTEXT *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( const INFCONTEXT *context_in, PCSTR key,
                                     INFCONTEXT *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( const INFCONTEXT *context_in, PCWSTR key,
                                     INFCONTEXT *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( const INFCONTEXT *context, HINF hinf, PCWSTR section_name,
                               PCWSTR key_name, PWSTR buffer, DWORD size, DWORD *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( const INFCONTEXT *context, HINF hinf, PCSTR section_name,
                               PCSTR key_name, PSTR buffer, DWORD size, DWORD *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( const INFCONTEXT *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( const INFCONTEXT *context, DWORD index, PSTR buffer,
                                  DWORD size, DWORD *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( const INFCONTEXT *context, DWORD index, PWSTR buffer,
                                  DWORD size, DWORD *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( const INFCONTEXT *context, DWORD index, INT *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( const INFCONTEXT *context, DWORD index, BYTE *buffer,
                                 DWORD size, DWORD *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 <<= 8) > 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++) DPRINTF( " %02x", buffer[i - index] );
        DPRINTF( "\n" );
    }
    return TRUE;
}


/***********************************************************************
 *		SetupGetMultiSzFieldA    (SETUPAPI.@)
 */
BOOL WINAPI SetupGetMultiSzFieldA( const INFCONTEXT *context, DWORD index, PSTR buffer,
                                   DWORD size, DWORD *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( const INFCONTEXT *context, DWORD index, PWSTR buffer,
                                   DWORD size, DWORD *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;
}
