<directory name="imm32">
<xi:include href="imm32/imm32.xml" />
</directory>
+<directory name="inflib">
+ <xi:include href="inflib/inflib.xml" />
+</directory>
<directory name="intrlck">
<xi:include href="intrlck/intrlck.xml" />
</directory>
--- /dev/null
+Routines to handle .inf files.
+
+This library is used to share .inf handling code between build tools and
+ReactOS code. Two versions are built, "inflib_host" (for use by build tools)
+and "inflib" (for use by ReactOS code). Both depend on the same core source,
+with a wrapper for the appropriate interface.
+Most of the differences between the host and the ReactOS environment are
+abstracted away in builddep.h. Of particular note is that the host version
+uses Ansi characters while the ReactOS version uses Unicode. So, the core
+source uses TCHARs. builddep.h depends on a preprocessor variable INFLIB_HOST
+which is defined when building the host version (inflib.mak) but not defined
+when building the ReactOS version (inflib.xml).
+The wrappers have "host" or "ros" in their filename. The library interface is
+"infhost.h" for the host version, "infros.h" for the ReactOS version.
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/builddep.h
+ * PURPOSE: Build dependent definitions
+ * PROGRAMMER: Ge van Geldorp <gvg@reactos.org>
+ */
+
+#ifdef INFLIB_HOST
+
+/* Definitions native to the host on which we're building */
+
+#include <string.h>
+#include <errno.h>
+
+#define FREE(Area) free(Area)
+#define MALLOC(Size) malloc(Size)
+#define ZEROMEMORY(Area, Size) memset((Area), '\0', (Size))
+#define MEMCPY(Dest, Src, Size) memcpy((Dest), (Src), (Size))
+
+#define INF_STATUS_SUCCESS 0
+#define INF_STATUS_NO_MEMORY ENOMEM
+#define INF_STATUS_INVALID_PARAMETER EINVAL
+#define INF_STATUS_NOT_FOUND ENOENT
+#define INF_STATUS_BUFFER_OVERFLOW E2BIG
+#define INF_SUCCESS(x) (0 == (x))
+
+typedef char CHAR, *PCHAR;
+typedef unsigned char UCHAR, *PUCHAR;
+typedef long LONG, *PLONG;
+typedef unsigned long ULONG, *PULONG;
+typedef void VOID, *PVOID;
+typedef UCHAR BOOLEAN, *PBOOLEAN;
+
+typedef char TCHAR, *PTCHAR, *PTSTR;
+#define _T(x) x
+#define _tcsicmp strcasecmp
+#define _tcslen strlen
+#define _tcscpy strcpy
+#define _tcstoul strtoul
+#define _tcstol strtol
+
+extern void DbgPrint(const char *Fmt, ...);
+
+#else /* ! defined(INFLIB_HOST) */
+
+/* ReactOS definitions */
+
+#define UNICODE
+#define _UNICODE
+#include <tchar.h>
+#define WIN32_NO_STATUS
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
+
+extern PVOID InfpHeap;
+
+#define FREE(Area) RtlFreeHeap(InfpHeap, 0, (Area))
+#define MALLOC(Size) RtlAllocateHeap(InfpHeap, 0, (Size))
+#define ZEROMEMORY(Area, Size) RtlZeroMemory((Area), (Size))
+#define MEMCPY(Dest, Src, Size) RtlCopyMemory((Dest), (Src), (Size))
+
+#define INF_STATUS_SUCCESS STATUS_SUCCESS
+#define INF_STATUS_NO_MEMORY STATUS_NO_MEMORY
+#define INF_STATUS_INVALID_PARAMETER STATUS_INVALID_PARAMETER
+#define INF_STATUS_NOT_FOUND STATUS_NOT_FOUND
+#define INF_STATUS_BUFFER_OVERFLOW STATUS_BUFFER_OVERFLOW
+#define INF_SUCCESS(x) (0 <= (x))
+
+#endif /* INFLIB_HOST */
+
+typedef const TCHAR *PCTSTR;
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infcommon.h
+ * PURPOSE: Public .inf routines
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+#ifndef INFCOMMON_H_INCLUDED
+#define INFCOMMON_H_INCLUDED
+
+#define MAX_INF_STRING_LENGTH 512
+
+typedef void *HINF, **PHINF;
+typedef struct _INFCONTEXT *PINFCONTEXT;
+
+#endif /* INFCOMMON_H_INCLUDED */
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infcore.c
+ * PURPOSE: INF file parser that caches contents of INF file in memory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#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)
+
+
+/* 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 CHAR *start; /* start position of item being parsed */
+ const CHAR *end; /* end of buffer */
+ PINFCACHE 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 */
+
+ PINFCACHESECTION cur_section; /* pointer to the section being parsed*/
+ PINFCACHELINE line; /* current line */
+ unsigned int line_pos; /* current line position in file */
+ unsigned int error; /* error code */
+ unsigned int token_len; /* current token len */
+ TCHAR token[MAX_FIELD_LEN+1]; /* current token */
+};
+
+typedef const CHAR * (*parser_state_func)( struct parser *parser, const CHAR *pos );
+
+/* parser state machine functions */
+static const CHAR *line_start_state( struct parser *parser, const CHAR *pos );
+static const CHAR *section_name_state( struct parser *parser, const CHAR *pos );
+static const CHAR *key_name_state( struct parser *parser, const CHAR *pos );
+static const CHAR *value_name_state( struct parser *parser, const CHAR *pos );
+static const CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos );
+static const CHAR *quotes_state( struct parser *parser, const CHAR *pos );
+static const CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos );
+static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos );
+static const CHAR *comment_state( struct parser *parser, const CHAR *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 */
+};
+
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+static PINFCACHELINE
+InfpCacheFreeLine (PINFCACHELINE Line)
+{
+ PINFCACHELINE Next;
+ PINFCACHEFIELD Field;
+
+ if (Line == NULL)
+ {
+ return NULL;
+ }
+
+ Next = Line->Next;
+ if (Line->Key != NULL)
+ {
+ FREE (Line->Key);
+ Line->Key = NULL;
+ }
+
+ /* Remove data fields */
+ while (Line->FirstField != NULL)
+ {
+ Field = Line->FirstField->Next;
+ FREE (Line->FirstField);
+ Line->FirstField = Field;
+ }
+ Line->LastField = NULL;
+
+ FREE (Line);
+
+ return Next;
+}
+
+
+PINFCACHESECTION
+InfpCacheFreeSection (PINFCACHESECTION Section)
+{
+ PINFCACHESECTION Next;
+
+ if (Section == NULL)
+ {
+ return NULL;
+ }
+
+ /* Release all keys */
+ Next = Section->Next;
+ while (Section->FirstLine != NULL)
+ {
+ Section->FirstLine = InfpCacheFreeLine (Section->FirstLine);
+ }
+ Section->LastLine = NULL;
+
+ FREE (Section);
+
+ return Next;
+}
+
+
+static PINFCACHESECTION
+InfpCacheFindSection (PINFCACHE Cache,
+ PCTSTR Name)
+{
+ PINFCACHESECTION Section = NULL;
+
+ if (Cache == NULL || Name == NULL)
+ {
+ return NULL;
+ }
+
+ /* iterate through list of sections */
+ Section = Cache->FirstSection;
+ while (Section != NULL)
+ {
+ if (_tcsicmp (Section->Name, Name) == 0)
+ {
+ return Section;
+ }
+
+ /* get the next section*/
+ Section = Section->Next;
+ }
+
+ return NULL;
+}
+
+
+static PINFCACHESECTION
+InfpCacheAddSection (PINFCACHE Cache,
+ PTCHAR Name)
+{
+ PINFCACHESECTION Section = NULL;
+ ULONG Size;
+
+ if (Cache == NULL || Name == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return NULL;
+ }
+
+ /* Allocate and initialize the new section */
+ Size = sizeof(INFCACHESECTION) + (_tcslen (Name) * sizeof(TCHAR));
+ Section = (PINFCACHESECTION)MALLOC (Size);
+ if (Section == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ return NULL;
+ }
+ ZEROMEMORY (Section,
+ Size);
+
+ /* Copy section name */
+ _tcscpy (Section->Name, Name);
+
+ /* Append section */
+ if (Cache->FirstSection == NULL)
+ {
+ Cache->FirstSection = Section;
+ Cache->LastSection = Section;
+ }
+ else
+ {
+ Cache->LastSection->Next = Section;
+ Section->Prev = Cache->LastSection;
+ Cache->LastSection = Section;
+ }
+
+ return Section;
+}
+
+
+static PINFCACHELINE
+InfpCacheAddLine (PINFCACHESECTION Section)
+{
+ PINFCACHELINE Line;
+
+ if (Section == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return NULL;
+ }
+
+ Line = (PINFCACHELINE)MALLOC (sizeof(INFCACHELINE));
+ if (Line == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ return NULL;
+ }
+ ZEROMEMORY(Line,
+ sizeof(INFCACHELINE));
+
+ /* Append line */
+ if (Section->FirstLine == NULL)
+ {
+ Section->FirstLine = Line;
+ Section->LastLine = Line;
+ }
+ else
+ {
+ Section->LastLine->Next = Line;
+ Line->Prev = Section->LastLine;
+ Section->LastLine = Line;
+ }
+ Section->LineCount++;
+
+ return Line;
+}
+
+
+static PVOID
+InfpAddKeyToLine (PINFCACHELINE Line,
+ PTCHAR Key)
+{
+ if (Line == NULL)
+ return NULL;
+
+ if (Line->Key != NULL)
+ return NULL;
+
+ Line->Key = (PTCHAR)MALLOC ((_tcslen (Key) + 1) * sizeof(TCHAR));
+ if (Line->Key == NULL)
+ return NULL;
+
+ _tcscpy (Line->Key, Key);
+
+ return (PVOID)Line->Key;
+}
+
+
+static PVOID
+InfpAddFieldToLine (PINFCACHELINE Line,
+ PTCHAR Data)
+{
+ PINFCACHEFIELD Field;
+ ULONG Size;
+
+ Size = sizeof(INFCACHEFIELD) + (_tcslen(Data) * sizeof(TCHAR));
+ Field = (PINFCACHEFIELD)MALLOC (Size);
+ if (Field == NULL)
+ {
+ return NULL;
+ }
+ ZEROMEMORY (Field,
+ Size);
+ _tcscpy (Field->Data, Data);
+
+ /* Append key */
+ if (Line->FirstField == NULL)
+ {
+ Line->FirstField = Field;
+ Line->LastField = Field;
+ }
+ else
+ {
+ Line->LastField->Next = Field;
+ Field->Prev = Line->LastField;
+ Line->LastField = Field;
+ }
+ Line->FieldCount++;
+
+ return (PVOID)Field;
+}
+
+
+PINFCACHELINE
+InfpCacheFindKeyLine (PINFCACHESECTION Section,
+ PTCHAR Key)
+{
+ PINFCACHELINE Line;
+
+ Line = Section->FirstLine;
+ while (Line != NULL)
+ {
+ if (Line->Key != NULL && _tcsicmp (Line->Key, Key) == 0)
+ {
+ return Line;
+ }
+
+ Line = Line->Next;
+ }
+
+ return NULL;
+}
+
+
+/* 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 CHAR *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 CHAR *ptr )
+{
+ return (ptr >= parser->end ||
+ *ptr == CONTROL_Z ||
+ *ptr == '\n' ||
+ (*ptr == '\r' && *(ptr + 1) == '\n'));
+}
+
+
+/* push data from current token start up to pos into the current token */
+static int push_token( struct parser *parser, const CHAR *pos )
+{
+ unsigned int len = pos - parser->start;
+ const CHAR *src = parser->start;
+ TCHAR *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 ? (TCHAR)*src : L' ';
+ *dst = 0;
+ parser->start = pos;
+
+ return 0;
+}
+
+
+
+/* add a section with the current token as name */
+static PVOID add_section_from_token( struct parser *parser )
+{
+ PINFCACHESECTION Section;
+
+ if (parser->token_len > MAX_SECTION_NAME_LEN)
+ {
+ parser->error = INF_STATUS_SECTION_NAME_TOO_LONG;
+ return NULL;
+ }
+
+ Section = InfpCacheFindSection (parser->file,
+ parser->token);
+ if (Section == NULL)
+ {
+ /* need to create a new one */
+ Section= InfpCacheAddSection (parser->file,
+ parser->token);
+ if (Section == NULL)
+ {
+ parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
+ return NULL;
+ }
+ }
+
+ parser->token_len = 0;
+ parser->cur_section = Section;
+
+ return (PVOID)Section;
+}
+
+
+/* add a field containing the current token to the current line */
+static struct field *add_field_from_token( struct parser *parser, int is_key )
+{
+ PVOID field;
+
+ if (!parser->line) /* need to start a new line */
+ {
+ if (parser->cur_section == NULL) /* got a line before the first section */
+ {
+ parser->error = INF_STATUS_WRONG_INF_STYLE;
+ return NULL;
+ }
+
+ parser->line = InfpCacheAddLine (parser->cur_section);
+ if (parser->line == NULL)
+ goto error;
+ }
+ else
+ {
+// assert(!is_key);
+ }
+
+ if (is_key)
+ {
+ field = InfpAddKeyToLine(parser->line, parser->token);
+ }
+ else
+ {
+ field = InfpAddFieldToLine(parser->line, parser->token);
+ }
+
+ if (field != NULL)
+ {
+ parser->token_len = 0;
+ return field;
+ }
+
+error:
+ parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
+ return NULL;
+}
+
+
+/* close the current line and prepare for parsing a new one */
+static void close_current_line( struct parser *parser )
+{
+ parser->line = NULL;
+}
+
+
+
+/* handler for parser LINE_START state */
+static const CHAR *line_start_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p;
+
+ for (p = pos; !is_eof( parser, p ); p++)
+ {
+ switch(*p)
+ {
+ case '\r':
+ continue;
+
+ 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 (!isspace(*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 CHAR *section_name_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p;
+
+ for (p = pos; !is_eol( parser, p ); p++)
+ {
+ if (*p == ']')
+ {
+ push_token( parser, p );
+ if (add_section_from_token( parser ) == NULL)
+ return NULL;
+ push_state( parser, LINE_START );
+ set_state( parser, COMMENT ); /* ignore everything else on the line */
+ return p + 1;
+ }
+ }
+ parser->error = INF_STATUS_BAD_SECTION_NAME_LINE; /* unfinished section name */
+ return NULL;
+}
+
+
+/* handler for parser KEY_NAME state */
+static const CHAR *key_name_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *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 (!isspace(*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 CHAR *value_name_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *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 (!isspace(*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 CHAR *eol_backslash_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p;
+
+ for (p = pos; !is_eof( parser, p ); p++)
+ {
+ switch(*p)
+ {
+ case '\r':
+ continue;
+
+ 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 (isspace(*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 CHAR *quotes_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *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 CHAR *leading_spaces_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p;
+
+ for (p = pos; !is_eol( parser, p ); p++)
+ {
+ if (*p == '\\')
+ {
+ parser->start = p;
+ set_state( parser, EOL_BACKSLASH );
+ return p;
+ }
+ if (!isspace(*p))
+ break;
+ }
+ parser->start = p;
+ pop_state( parser );
+ return p;
+}
+
+
+/* handler for parser TRAILING_SPACES state */
+static const CHAR *trailing_spaces_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p;
+
+ for (p = pos; !is_eol( parser, p ); p++)
+ {
+ if (*p == '\\')
+ {
+ set_state( parser, EOL_BACKSLASH );
+ return p;
+ }
+ if (!isspace(*p))
+ break;
+ }
+ pop_state( parser );
+ return p;
+}
+
+
+/* handler for parser COMMENT state */
+static const CHAR *comment_state( struct parser *parser, const CHAR *pos )
+{
+ const CHAR *p = pos;
+
+ while (!is_eol( parser, p ))
+ p++;
+ pop_state( parser );
+ return p;
+}
+
+
+/* parse a complete buffer */
+INFSTATUS
+InfpParseBuffer (PINFCACHE file,
+ const CHAR *buffer,
+ const CHAR *end,
+ PULONG error_line)
+{
+ struct parser parser;
+ const CHAR *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 = NULL;
+ parser.line_pos = 1;
+ parser.error = 0;
+ parser.token_len = 0;
+
+ /* parser main loop */
+ while (pos)
+ pos = (parser_funcs[parser.state])(&parser, pos);
+
+ if (parser.error)
+ {
+ if (error_line)
+ *error_line = parser.line_pos;
+ return parser.error;
+ }
+
+ /* find the [strings] section */
+ file->StringsSection = InfpCacheFindSection (file,
+ _T("Strings"));
+
+ return INF_STATUS_SUCCESS;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infrosget.c
+ * PURPOSE: Read .inf routines for use in ReactOS
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+INFSTATUS
+InfpFindFirstLine(HINF InfHandle,
+ PCTSTR Section,
+ PCTSTR Key,
+ PINFCONTEXT *Context)
+{
+ PINFCACHE Cache;
+ PINFCACHESECTION CacheSection;
+ PINFCACHELINE CacheLine;
+
+ if (InfHandle == NULL || Section == NULL || Context == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ *Context = MALLOC(sizeof(INFCONTEXT));
+ if (NULL == *Context)
+ {
+ DPRINT1("MALLOC() failed\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+
+ Cache = (PINFCACHE)InfHandle;
+
+ /* Iterate through list of sections */
+ CacheSection = Cache->FirstSection;
+ while (CacheSection != NULL)
+ {
+ DPRINT("Comparing '%S' and '%S'\n", CacheSection->Name, Section);
+
+ /* Are the section names the same? */
+ if (_tcsicmp(CacheSection->Name, Section) == 0)
+ {
+ if (Key != NULL)
+ {
+ CacheLine = InfpCacheFindKeyLine (CacheSection, (PTCHAR)Key);
+ }
+ else
+ {
+ CacheLine = CacheSection->FirstLine;
+ }
+
+ if (CacheLine == NULL)
+ return INF_STATUS_NOT_FOUND;
+
+ (*Context)->Inf = (PVOID)Cache;
+ (*Context)->Section = (PVOID)CacheSection;
+ (*Context)->Line = (PVOID)CacheLine;
+
+ return INF_STATUS_SUCCESS;
+ }
+
+ /* Get the next section */
+ CacheSection = CacheSection->Next;
+ }
+
+ DPRINT("Section not found\n");
+
+ return INF_STATUS_NOT_FOUND;
+}
+
+
+INFSTATUS
+InfpFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut)
+{
+ PINFCACHELINE CacheLine;
+
+ if (ContextIn == NULL || ContextOut == NULL)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ if (ContextIn->Line == NULL)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ CacheLine = (PINFCACHELINE)ContextIn->Line;
+ if (CacheLine->Next == NULL)
+ return INF_STATUS_NOT_FOUND;
+
+ if (ContextIn != ContextOut)
+ {
+ ContextOut->Inf = ContextIn->Inf;
+ ContextOut->Section = ContextIn->Section;
+ }
+ ContextOut->Line = (PVOID)(CacheLine->Next);
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpFindFirstMatchLine(PINFCONTEXT ContextIn,
+ PCTSTR Key,
+ PINFCONTEXT ContextOut)
+{
+ PINFCACHELINE CacheLine;
+
+ if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ if (ContextIn->Inf == NULL || ContextIn->Section == NULL)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine;
+ while (CacheLine != NULL)
+ {
+ if (CacheLine->Key != NULL && _tcsicmp (CacheLine->Key, Key) == 0)
+ {
+
+ if (ContextIn != ContextOut)
+ {
+ ContextOut->Inf = ContextIn->Inf;
+ ContextOut->Section = ContextIn->Section;
+ }
+ ContextOut->Line = (PVOID)CacheLine;
+
+ return INF_STATUS_SUCCESS;
+ }
+
+ CacheLine = CacheLine->Next;
+ }
+
+ return INF_STATUS_NOT_FOUND;
+}
+
+
+INFSTATUS
+InfpFindNextMatchLine(PINFCONTEXT ContextIn,
+ PCTSTR Key,
+ PINFCONTEXT ContextOut)
+{
+ PINFCACHELINE CacheLine;
+
+ if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ CacheLine = (PINFCACHELINE)ContextIn->Line;
+ while (CacheLine != NULL)
+ {
+ if (CacheLine->Key != NULL && _tcsicmp (CacheLine->Key, Key) == 0)
+ {
+
+ if (ContextIn != ContextOut)
+ {
+ ContextOut->Inf = ContextIn->Inf;
+ ContextOut->Section = ContextIn->Section;
+ }
+ ContextOut->Line = (PVOID)CacheLine;
+
+ return INF_STATUS_SUCCESS;
+ }
+
+ CacheLine = CacheLine->Next;
+ }
+
+ return INF_STATUS_NOT_FOUND;
+}
+
+
+LONG
+InfpGetLineCount(HINF InfHandle,
+ PCTSTR Section)
+{
+ PINFCACHE Cache;
+ PINFCACHESECTION CacheSection;
+
+ if (InfHandle == NULL || Section == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return -1;
+ }
+
+ Cache = (PINFCACHE)InfHandle;
+
+ /* Iterate through list of sections */
+ CacheSection = Cache->FirstSection;
+ while (CacheSection != NULL)
+ {
+ /* Are the section names the same? */
+ if (_tcsicmp(CacheSection->Name, Section) == 0)
+ {
+ return CacheSection->LineCount;
+ }
+
+ /* Get the next section */
+ CacheSection = CacheSection->Next;
+ }
+
+ DPRINT("Section not found\n");
+
+ return -1;
+}
+
+
+/* InfpGetLineText */
+
+
+LONG
+InfpGetFieldCount(PINFCONTEXT Context)
+{
+ if (Context == NULL || Context->Line == NULL)
+ return 0;
+
+ return ((PINFCACHELINE)Context->Line)->FieldCount;
+}
+
+
+INFSTATUS
+InfpGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ ULONG Index;
+ ULONG Size;
+ PUCHAR Ptr;
+
+ if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ if (RequiredSize != NULL)
+ *RequiredSize = 0;
+
+ CacheLine = (PINFCACHELINE)Context->Line;
+
+ if (FieldIndex > (ULONG)CacheLine->FieldCount)
+ return INF_STATUS_NOT_FOUND;
+
+ CacheField = CacheLine->FirstField;
+ for (Index = 1; Index < FieldIndex; Index++)
+ CacheField = CacheField->Next;
+
+ Size = CacheLine->FieldCount - FieldIndex + 1;
+
+ if (RequiredSize != NULL)
+ *RequiredSize = Size;
+
+ if (ReturnBuffer != NULL)
+ {
+ if (ReturnBufferSize < Size)
+ return INF_STATUS_BUFFER_OVERFLOW;
+
+ /* Copy binary data */
+ Ptr = ReturnBuffer;
+ while (CacheField != NULL)
+ {
+ *Ptr = (UCHAR)_tcstoul (CacheField->Data, NULL, 16);
+
+ Ptr++;
+ CacheField = CacheField->Next;
+ }
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PLONG IntegerValue)
+{
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ ULONG Index;
+ PTCHAR Ptr;
+
+ if (Context == NULL || Context->Line == NULL || IntegerValue == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ CacheLine = (PINFCACHELINE)Context->Line;
+
+ if (FieldIndex > (ULONG)CacheLine->FieldCount)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ if (FieldIndex == 0)
+ {
+ Ptr = CacheLine->Key;
+ }
+ else
+ {
+ CacheField = CacheLine->FirstField;
+ for (Index = 1; Index < FieldIndex; Index++)
+ CacheField = CacheField->Next;
+
+ Ptr = CacheField->Data;
+ }
+
+ *IntegerValue = _tcstol(Ptr, NULL, 0);
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetMultiSzField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ PINFCACHEFIELD FieldPtr;
+ ULONG Index;
+ ULONG Size;
+ PTCHAR Ptr;
+
+ if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ if (RequiredSize != NULL)
+ *RequiredSize = 0;
+
+ CacheLine = (PINFCACHELINE)Context->Line;
+
+ if (FieldIndex > (ULONG)CacheLine->FieldCount)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ CacheField = CacheLine->FirstField;
+ for (Index = 1; Index < FieldIndex; Index++)
+ CacheField = CacheField->Next;
+
+ /* Calculate the required buffer size */
+ FieldPtr = CacheField;
+ Size = 0;
+ while (FieldPtr != NULL)
+ {
+ Size += (_tcslen (FieldPtr->Data) + 1);
+ FieldPtr = FieldPtr->Next;
+ }
+ Size++;
+
+ if (RequiredSize != NULL)
+ *RequiredSize = Size;
+
+ if (ReturnBuffer != NULL)
+ {
+ if (ReturnBufferSize < Size)
+ return INF_STATUS_BUFFER_OVERFLOW;
+
+ /* Copy multi-sz string */
+ Ptr = ReturnBuffer;
+ FieldPtr = CacheField;
+ while (FieldPtr != NULL)
+ {
+ Size = _tcslen (FieldPtr->Data) + 1;
+
+ _tcscpy (Ptr, FieldPtr->Data);
+
+ Ptr = Ptr + Size;
+ FieldPtr = FieldPtr->Next;
+ }
+ *Ptr = 0;
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetStringField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ ULONG Index;
+ PTCHAR Ptr;
+ ULONG Size;
+
+ if (Context == NULL || Context->Line == NULL || FieldIndex == 0)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ if (RequiredSize != NULL)
+ *RequiredSize = 0;
+
+ CacheLine = (PINFCACHELINE)Context->Line;
+
+ if (FieldIndex > (ULONG)CacheLine->FieldCount)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ if (FieldIndex == 0)
+ {
+ Ptr = CacheLine->Key;
+ }
+ else
+ {
+ CacheField = CacheLine->FirstField;
+ for (Index = 1; Index < FieldIndex; Index++)
+ CacheField = CacheField->Next;
+
+ Ptr = CacheField->Data;
+ }
+
+ Size = _tcslen (Ptr) + 1;
+
+ if (RequiredSize != NULL)
+ *RequiredSize = Size;
+
+ if (ReturnBuffer != NULL)
+ {
+ if (ReturnBufferSize < Size)
+ return INF_STATUS_BUFFER_OVERFLOW;
+
+ _tcscpy (ReturnBuffer, Ptr);
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetData(PINFCONTEXT Context,
+ PTCHAR *Key,
+ PTCHAR *Data)
+{
+ PINFCACHELINE CacheKey;
+
+ if (Context == NULL || Context->Line == NULL || Data == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ CacheKey = (PINFCACHELINE)Context->Line;
+ if (Key != NULL)
+ *Key = CacheKey->Key;
+
+ if (Data != NULL)
+ {
+ if (CacheKey->FirstField == NULL)
+ {
+ *Data = NULL;
+ }
+ else
+ {
+ *Data = CacheKey->FirstField->Data;
+ }
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+
+INFSTATUS
+InfpGetDataField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTCHAR *Data)
+{
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ ULONG Index;
+
+ if (Context == NULL || Context->Line == NULL || Data == NULL)
+ {
+ DPRINT("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ CacheLine = (PINFCACHELINE)Context->Line;
+
+ if (FieldIndex > (ULONG)CacheLine->FieldCount)
+ return INF_STATUS_INVALID_PARAMETER;
+
+ if (FieldIndex == 0)
+ {
+ *Data = CacheLine->Key;
+ }
+ else
+ {
+ CacheField = CacheLine->FirstField;
+ for (Index = 1; Index < FieldIndex; Index++)
+ CacheField = CacheField->Next;
+
+ *Data = CacheField->Data;
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+VOID
+InfpFreeContext(PINFCONTEXT Context)
+{
+ FREE(Context);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infros.h
+ * PURPOSE: Public .inf routines for use on the host build system
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+#ifndef INFHOST_H_INCLUDED
+#define INFHOST_H_INCLUDED
+
+#include <infcommon.h>
+
+extern int InfHostOpenBufferedFile(PHINF InfHandle,
+ void *Buffer,
+ unsigned long BufferSize,
+ unsigned long *ErrorLine);
+extern int InfHostOpenFile(PHINF InfHandle,
+ char *FileName,
+ unsigned long *ErrorLine);
+extern void InfHostCloseFile(HINF InfHandle);
+extern int InfHostFindFirstLine(HINF InfHandle,
+ const char *Section,
+ const char *Key,
+ PINFCONTEXT *Context);
+extern int InfHostFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut);
+extern int InfHostFindFirstMatchLine(PINFCONTEXT ContextIn,
+ const char *Key,
+ PINFCONTEXT ContextOut);
+extern int InfHostFindNextMatchLine(PINFCONTEXT ContextIn,
+ const char *Key,
+ PINFCONTEXT ContextOut);
+extern long InfHostGetLineCount(HINF InfHandle,
+ const char *Section);
+extern long InfHostGetFieldCount(PINFCONTEXT Context);
+extern int InfHostGetBinaryField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ unsigned char *ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize);
+extern int InfHostGetIntField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ unsigned long *IntegerValue);
+extern int InfHostGetMultiSzField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char *ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize);
+extern int InfHostGetStringField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char *ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize);
+extern int InfHostGetData(PINFCONTEXT Context,
+ char **Key,
+ char **Data);
+extern int InfHostGetDataField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char **Data);
+extern VOID InfHostFreeContext(PINFCONTEXT Context);
+
+#endif /* INFROS_H_INCLUDED */
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infhostgen.c
+ * PURPOSE: General .inf routines for use on the host build system
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <stdio.h>
+#include <errno.h>
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+int
+InfHostOpenBufferedFile(PHINF InfHandle,
+ void *Buffer,
+ unsigned long BufferSize,
+ unsigned long *ErrorLine)
+{
+ INFSTATUS Status;
+ PINFCACHE Cache;
+ char *FileBuffer;
+
+ *InfHandle = NULL;
+ *ErrorLine = (unsigned long)-1;
+
+ /* Allocate file buffer */
+ FileBuffer = MALLOC(BufferSize + 1);
+ if (FileBuffer == NULL)
+ {
+ DPRINT1("MALLOC() failed\n");
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ MEMCPY(FileBuffer, Buffer, BufferSize);
+
+ /* Append string terminator */
+ FileBuffer[BufferSize] = 0;
+
+ /* Allocate infcache header */
+ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+ if (Cache == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ FREE(FileBuffer);
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* Initialize inicache header */
+ ZEROMEMORY(Cache,
+ sizeof(INFCACHE));
+
+ /* Parse the inf buffer */
+ Status = InfpParseBuffer (Cache,
+ FileBuffer,
+ FileBuffer + BufferSize,
+ ErrorLine);
+ if (!INF_SUCCESS(Status))
+ {
+ FREE(Cache);
+ Cache = NULL;
+ }
+
+ /* Free file buffer */
+ FREE(FileBuffer);
+
+ *InfHandle = (HINF)Cache;
+
+ return INF_SUCCESS(Status) ? 0 : -1;
+}
+
+
+int
+InfHostOpenFile(PHINF InfHandle,
+ char *FileName,
+ unsigned long *ErrorLine)
+{
+ FILE *File;
+ char *FileBuffer;
+ unsigned long FileLength;
+ PINFCACHE Cache;
+ INFSTATUS Status;
+
+ *InfHandle = NULL;
+ *ErrorLine = (unsigned long)-1;
+
+ /* Open the inf file */
+ File = fopen(FileName, "rb");
+ if (NULL == File)
+ {
+ DPRINT("fopen() failed (errno %d)\n", errno);
+ return -1;
+ }
+
+ DPRINT("fopen() successful\n");
+
+ /* Query file size */
+ if (fseek(File, 0, SEEK_END))
+ {
+ DPRINT("fseek() to EOF failed (errno %d)\n", errno);
+ fclose(File);
+ return -1;
+ }
+
+ FileLength = ftell(File);
+ if ((unsigned long) -1 == FileLength)
+ {
+ DPRINT("ftell() failed (errno %d)\n", errno);
+ fclose(File);
+ return -1;
+ }
+ DPRINT("File size: %lu\n", FileLength);
+
+ /* Rewind */
+ if (fseek(File, 0, SEEK_SET))
+ {
+ DPRINT("fseek() to BOF failed (errno %d)\n", errno);
+ fclose(File);
+ return -1;
+ }
+
+ /* Allocate file buffer */
+ FileBuffer = MALLOC(FileLength + 1);
+ if (FileBuffer == NULL)
+ {
+ DPRINT1("MALLOC() failed\n");
+ fclose(File);
+ return -1;
+ }
+
+ /* Read file */
+ if (FileLength != fread(FileBuffer, 1, FileLength, File))
+ {
+ DPRINT("fread() failed (errno %d)\n", errno);
+ fclose(File);
+ return -1;
+ }
+
+ fclose(File);
+
+ /* Append string terminator */
+ FileBuffer[FileLength] = 0;
+
+ /* Allocate infcache header */
+ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+ if (Cache == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ FREE(FileBuffer);
+ return -1;
+ }
+
+ /* Initialize inicache header */
+ ZEROMEMORY(Cache,
+ sizeof(INFCACHE));
+
+ /* Parse the inf buffer */
+ Status = InfpParseBuffer (Cache,
+ FileBuffer,
+ FileBuffer + FileLength,
+ ErrorLine);
+ if (!INF_SUCCESS(Status))
+ {
+ FREE(Cache);
+ Cache = NULL;
+ }
+
+ /* Free file buffer */
+ FREE(FileBuffer);
+
+ *InfHandle = (HINF)Cache;
+
+ return INF_SUCCESS(Status) ? 0 : -1;
+}
+
+
+void
+InfHostCloseFile(HINF InfHandle)
+{
+ PINFCACHE Cache;
+
+ Cache = (PINFCACHE)InfHandle;
+
+ if (Cache == NULL)
+ {
+ return;
+ }
+
+ while (Cache->FirstSection != NULL)
+ {
+ Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
+ }
+ Cache->LastSection = NULL;
+
+ FREE(Cache);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infrosget.c
+ * PURPOSE: Read .inf routines for use on the host build system
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <errno.h>
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+int
+InfHostFindFirstLine(HINF InfHandle,
+ const char *Section,
+ const char *Key,
+ PINFCONTEXT *Context)
+{
+ INFSTATUS Status;
+
+ Status = InfpFindFirstLine(InfHandle, Section, Key, Context);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut)
+{
+ INFSTATUS Status;
+
+ Status = InfpFindNextLine(ContextIn, ContextOut);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostFindFirstMatchLine(PINFCONTEXT ContextIn,
+ const char *Key,
+ PINFCONTEXT ContextOut)
+{
+ INFSTATUS Status;
+
+ Status = InfpFindFirstMatchLine(ContextIn, Key, ContextOut);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostFindNextMatchLine(PINFCONTEXT ContextIn,
+ const char *Key,
+ PINFCONTEXT ContextOut)
+{
+ INFSTATUS Status;
+
+ Status = InfpFindNextMatchLine(ContextIn, Key, ContextOut);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+long
+InfHostGetLineCount(HINF InfHandle,
+ PCTSTR Section)
+{
+ return InfpGetLineCount(InfHandle, Section);
+}
+
+
+/* InfGetLineText */
+
+
+long
+InfHostGetFieldCount(PINFCONTEXT Context)
+{
+ return InfpGetFieldCount(Context);
+}
+
+
+int
+InfHostGetBinaryField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ unsigned char *ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetBinaryField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostGetIntField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ unsigned long *IntegerValue)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetIntField(Context, FieldIndex, IntegerValue);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostGetMultiSzField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char * ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetMultiSzField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostGetStringField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char *ReturnBuffer,
+ unsigned long ReturnBufferSize,
+ unsigned long *RequiredSize)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetStringField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostGetData(PINFCONTEXT Context,
+ char **Key,
+ char **Data)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetData(Context, Key, Data);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+
+int
+InfHostGetDataField(PINFCONTEXT Context,
+ unsigned long FieldIndex,
+ char **Data)
+{
+ INFSTATUS Status;
+
+ Status = InfpGetDataField(Context, FieldIndex, Data);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+VOID
+InfHostFreeContext(PINFCONTEXT Context)
+{
+ InfpFreeContext(Context);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/inflib.h
+ * PURPOSE: Pre-compiled header
+ * PROGRAMMER: Ge van Geldorp <gvg@reactos.org>
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "builddep.h"
+#include "infcommon.h"
+#include "infpriv.h"
+
+/* EOF */
--- /dev/null
+INFLIB_BASE = $(LIB_BASE_)inflib
+INFLIB_BASE_ = $(INFLIB_BASE)$(SEP)
+INFLIB_INT = $(INTERMEDIATE_)$(INFLIB_BASE)_host
+INFLIB_INT_ = $(INTERMEDIATE_)$(INFLIB_BASE)_host$(SEP)
+INFLIB_OUT = $(OUTPUT_)$(INFLIB_BASE)_host
+INFLIB_OUT_ = $(OUTPUT_)$(INFLIB_BASE)_host$(SEP)
+
+$(INFLIB_INT): | $(LIB_INT)
+ $(ECHO_MKDIR)
+ ${mkdir} $@
+
+ifneq ($(INTERMEDIATE),$(OUTPUT))
+$(INFLIB_OUT): | $(OUTPUT_)$(LIB_BASE)
+ $(ECHO_MKDIR)
+ ${mkdir} $@
+endif
+
+INFLIB_HOST_TARGET = \
+ $(INFLIB_OUT)$(SEP)inflib.a
+
+INFLIB_HOST_SOURCES = $(addprefix $(INFLIB_BASE_), \
+ infcore.c \
+ infget.c \
+ infhostgen.c \
+ infhostget.c \
+ )
+
+INFLIB_HOST_OBJECTS = \
+ $(subst $(INFLIB_BASE), $(INFLIB_INT), $(INFLIB_HOST_SOURCES:.c=.o))
+
+INFLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes -DINFLIB_HOST -D_M_IX86 \
+ -I$(INFLIB_BASE) -Iinclude/reactos
+
+$(INFLIB_HOST_TARGET): $(INFLIB_HOST_OBJECTS) | $(INFLIB_OUT)
+ $(ECHO_AR)
+ $(host_ar) -r $@ $(INFLIB_HOST_OBJECTS)
+
+$(INFLIB_INT_)infcore.o: $(INFLIB_BASE_)infcore.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infget.o: $(INFLIB_BASE_)infget.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostgen.o: $(INFLIB_BASE_)infhostgen.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostget.o: $(INFLIB_BASE_)infhostget.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+.PHONY: inflib_host
+inflib_host: $(INFLIB_HOST_TARGET)
+
+.PHONY: inflib_host_clean
+inflib_host_clean:
+ -@$(rm) $(INFLIB_HOST_TARGET) $(INFLIB_HOST_OBJECTS) 2>$(NUL)
+clean: inflib_host_clean
--- /dev/null
+<module name="inflib" type="staticlibrary">
+ <include base="inflib">.</include>
+ <pch>inflib.h</pch>
+ <file>infcore.c</file>
+ <file>infget.c</file>
+ <file>infrosgen.c</file>
+ <file>infrosget.c</file>
+</module>
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infcache.h
+ * PURPOSE: INF file parser that caches contents of INF file in memory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
+ */
+
+#ifndef INFPRIV_H_INCLUDED
+#define INFPRIV_H_INCLUDED
+
+
+#define INF_STATUS_INSUFFICIENT_RESOURCES (0xC000009A)
+#define INF_STATUS_BAD_SECTION_NAME_LINE (0xC0700001)
+#define INF_STATUS_SECTION_NAME_TOO_LONG (0xC0700002)
+#define INF_STATUS_WRONG_INF_STYLE (0xC0700003)
+#define INF_STATUS_NOT_ENOUGH_MEMORY (0xC0700004)
+
+typedef struct _INFCONTEXT
+{
+ PVOID Inf;
+ PVOID Section;
+ PVOID Line;
+} INFCONTEXT;
+
+typedef struct _INFCACHEFIELD
+{
+ struct _INFCACHEFIELD *Next;
+ struct _INFCACHEFIELD *Prev;
+
+ TCHAR Data[1];
+} INFCACHEFIELD, *PINFCACHEFIELD;
+
+typedef struct _INFCACHELINE
+{
+ struct _INFCACHELINE *Next;
+ struct _INFCACHELINE *Prev;
+
+ LONG FieldCount;
+
+ PTCHAR Key;
+
+ PINFCACHEFIELD FirstField;
+ PINFCACHEFIELD LastField;
+
+} INFCACHELINE, *PINFCACHELINE;
+
+typedef struct _INFCACHESECTION
+{
+ struct _INFCACHESECTION *Next;
+ struct _INFCACHESECTION *Prev;
+
+ PINFCACHELINE FirstLine;
+ PINFCACHELINE LastLine;
+
+ LONG LineCount;
+
+ TCHAR Name[1];
+} INFCACHESECTION, *PINFCACHESECTION;
+
+typedef struct _INFCACHE
+{
+ PINFCACHESECTION FirstSection;
+ PINFCACHESECTION LastSection;
+
+ PINFCACHESECTION StringsSection;
+} INFCACHE, *PINFCACHE;
+
+typedef long INFSTATUS;
+
+/* FUNCTIONS ****************************************************************/
+
+extern INFSTATUS InfpParseBuffer(PINFCACHE file,
+ const CHAR *buffer,
+ const CHAR *end,
+ PULONG error_line);
+extern PINFCACHESECTION InfpCacheFreeSection(PINFCACHESECTION Section);
+extern PINFCACHELINE InfpCacheFindKeyLine(PINFCACHESECTION Section,
+ PTCHAR Key);
+
+extern INFSTATUS InfpFindFirstLine(HINF InfHandle,
+ PCTSTR Section,
+ PCTSTR Key,
+ PINFCONTEXT *Context);
+extern INFSTATUS InfpFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut);
+extern INFSTATUS InfpFindFirstMatchLine(PINFCONTEXT ContextIn,
+ PCTSTR Key,
+ PINFCONTEXT ContextOut);
+extern INFSTATUS InfpFindNextMatchLine(PINFCONTEXT ContextIn,
+ PCTSTR Key,
+ PINFCONTEXT ContextOut);
+extern LONG InfpGetLineCount(HINF InfHandle,
+ PCTSTR Section);
+extern LONG InfpGetFieldCount(PINFCONTEXT Context);
+extern INFSTATUS InfpGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern INFSTATUS InfpGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PLONG IntegerValue);
+extern INFSTATUS InfpGetMultiSzField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern INFSTATUS InfpGetStringField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern INFSTATUS InfpGetData(PINFCONTEXT Context,
+ PTCHAR *Key,
+ PTCHAR *Data);
+extern INFSTATUS InfpGetDataField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PTCHAR *Data);
+extern VOID InfpFreeContext(PINFCONTEXT Context);
+
+#endif /* INFPRIV_H_INCLUDED */
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infros.h
+ * PURPOSE: Public .inf routines for use in ReactOS
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+#ifndef INFROS_H_INCLUDED
+#define INFROS_H_INCLUDED
+
+#include <infcommon.h>
+
+extern VOID InfSetHeap(PVOID Heap);
+extern NTSTATUS InfOpenBufferedFile(PHINF InfHandle,
+ PVOID Buffer,
+ ULONG BufferSize,
+ PULONG ErrorLine);
+extern NTSTATUS InfOpenFile(PHINF InfHandle,
+ PUNICODE_STRING FileName,
+ PULONG ErrorLine);
+extern VOID InfCloseFile(HINF InfHandle);
+extern BOOLEAN InfFindFirstLine(HINF InfHandle,
+ PCWSTR Section,
+ PCWSTR Key,
+ PINFCONTEXT *Context);
+extern BOOLEAN InfFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut);
+extern BOOLEAN InfFindFirstMatchLine(PINFCONTEXT ContextIn,
+ PCWSTR Key,
+ PINFCONTEXT ContextOut);
+extern BOOLEAN InfFindNextMatchLine(PINFCONTEXT ContextIn,
+ PCWSTR Key,
+ PINFCONTEXT ContextOut);
+extern LONG InfGetLineCount(HINF InfHandle,
+ PCWSTR Section);
+extern LONG InfGetFieldCount(PINFCONTEXT Context);
+extern BOOLEAN InfGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern BOOLEAN InfGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PLONG IntegerValue);
+extern BOOLEAN InfGetMultiSzField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern BOOLEAN InfGetStringField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize);
+extern BOOLEAN InfGetData(PINFCONTEXT Context,
+ PWCHAR *Key,
+ PWCHAR *Data);
+extern BOOLEAN InfGetDataField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWCHAR *Data);
+extern VOID InfFreeContext(PINFCONTEXT Context);
+
+#endif /* INFROS_H_INCLUDED */
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infrosgen.c
+ * PURPOSE: General .inf routines for use in ReactOS
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+static int InfpHeapRefCount;
+
+static VOID
+CheckHeap()
+{
+ if (NULL == InfpHeap)
+ {
+ InfpHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
+ }
+ if (0 <= InfpHeapRefCount)
+ {
+ InfpHeapRefCount++;
+ }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+PVOID InfpHeap;
+
+VOID
+InfSetHeap(PVOID Heap)
+{
+ if (NULL == InfpHeap)
+ {
+ InfpHeap = Heap;
+ InfpHeapRefCount = -1;
+ }
+}
+
+
+NTSTATUS
+InfOpenBufferedFile(PHINF InfHandle,
+ PVOID Buffer,
+ ULONG BufferSize,
+ PULONG ErrorLine)
+{
+ INFSTATUS Status;
+ PINFCACHE Cache;
+ PCHAR FileBuffer;
+
+ CheckHeap();
+
+ *InfHandle = NULL;
+ *ErrorLine = (ULONG)-1;
+
+ /* Allocate file buffer */
+ FileBuffer = MALLOC(BufferSize + 1);
+ if (FileBuffer == NULL)
+ {
+ DPRINT1("MALLOC() failed\n");
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ MEMCPY(FileBuffer, Buffer, BufferSize);
+
+ /* Append string terminator */
+ FileBuffer[BufferSize] = 0;
+
+ /* Allocate infcache header */
+ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+ if (Cache == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ FREE(FileBuffer);
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* Initialize inicache header */
+ ZEROMEMORY(Cache,
+ sizeof(INFCACHE));
+
+ /* Parse the inf buffer */
+ Status = InfpParseBuffer (Cache,
+ FileBuffer,
+ FileBuffer + BufferSize,
+ ErrorLine);
+ if (!INF_SUCCESS(Status))
+ {
+ FREE(Cache);
+ Cache = NULL;
+ }
+
+ /* Free file buffer */
+ FREE(FileBuffer);
+
+ *InfHandle = (HINF)Cache;
+
+ return(Status);
+}
+
+
+NTSTATUS
+InfOpenFile(PHINF InfHandle,
+ PUNICODE_STRING FileName,
+ PULONG ErrorLine)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ FILE_STANDARD_INFORMATION FileInfo;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+ PCHAR FileBuffer;
+ ULONG FileLength;
+ LARGE_INTEGER FileOffset;
+ PINFCACHE Cache;
+
+ CheckHeap();
+
+ *InfHandle = NULL;
+ *ErrorLine = (ULONG)-1;
+
+ /* Open the inf file */
+ InitializeObjectAttributes(&ObjectAttributes,
+ FileName,
+ 0,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (!INF_SUCCESS(Status))
+ {
+ DPRINT("NtOpenFile() failed (Status %lx)\n", Status);
+ return(Status);
+ }
+
+ DPRINT("NtOpenFile() successful\n");
+
+ /* Query file size */
+ Status = NtQueryInformationFile(FileHandle,
+ &IoStatusBlock,
+ &FileInfo,
+ sizeof(FILE_STANDARD_INFORMATION),
+ FileStandardInformation);
+ if (!INF_SUCCESS(Status))
+ {
+ DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
+ NtClose(FileHandle);
+ return(Status);
+ }
+
+ FileLength = FileInfo.EndOfFile.u.LowPart;
+
+ DPRINT("File size: %lu\n", FileLength);
+
+ /* Allocate file buffer */
+ FileBuffer = MALLOC(FileLength + 1);
+ if (FileBuffer == NULL)
+ {
+ DPRINT1("MALLOC() failed\n");
+ NtClose(FileHandle);
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* Read file */
+ FileOffset.QuadPart = 0ULL;
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FileBuffer,
+ FileLength,
+ &FileOffset,
+ NULL);
+
+ /* Append string terminator */
+ FileBuffer[FileLength] = 0;
+
+ NtClose(FileHandle);
+
+ if (!INF_SUCCESS(Status))
+ {
+ DPRINT("NtReadFile() failed (Status %lx)\n", Status);
+ FREE(FileBuffer);
+ return(Status);
+ }
+
+ /* Allocate infcache header */
+ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
+ if (Cache == NULL)
+ {
+ DPRINT("MALLOC() failed\n");
+ FREE(FileBuffer);
+ return(INF_STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ /* Initialize inicache header */
+ ZEROMEMORY(Cache,
+ sizeof(INFCACHE));
+
+ /* Parse the inf buffer */
+ Status = InfpParseBuffer (Cache,
+ FileBuffer,
+ FileBuffer + FileLength,
+ ErrorLine);
+ if (!INF_SUCCESS(Status))
+ {
+ FREE(Cache);
+ Cache = NULL;
+ }
+
+ /* Free file buffer */
+ FREE(FileBuffer);
+
+ *InfHandle = (HINF)Cache;
+
+ return(Status);
+}
+
+
+VOID
+InfCloseFile(HINF InfHandle)
+{
+ PINFCACHE Cache;
+
+ Cache = (PINFCACHE)InfHandle;
+
+ if (Cache == NULL)
+ {
+ return;
+ }
+
+ while (Cache->FirstSection != NULL)
+ {
+ Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
+ }
+ Cache->LastSection = NULL;
+
+ FREE(Cache);
+
+ if (0 < InfpHeapRefCount)
+ {
+ InfpHeapRefCount--;
+ if (0 == InfpHeapRefCount)
+ {
+ RtlDestroyHeap(InfpHeap);
+ InfpHeap = NULL;
+ }
+ }
+}
+
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: .inf file parser
+ * FILE: lib/inflib/infrosget.c
+ * PURPOSE: Read .inf routines for use in ReactOS
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+BOOLEAN
+InfFindFirstLine(HINF InfHandle,
+ PCWSTR Section,
+ PCWSTR Key,
+ PINFCONTEXT *Context)
+{
+ return INF_SUCCESS(InfpFindFirstLine(InfHandle, Section, Key, Context));
+}
+
+
+BOOLEAN
+InfFindNextLine(PINFCONTEXT ContextIn,
+ PINFCONTEXT ContextOut)
+{
+ return INF_SUCCESS(InfpFindNextLine(ContextIn, ContextOut));
+}
+
+
+BOOLEAN
+InfFindFirstMatchLine(PINFCONTEXT ContextIn,
+ PCWSTR Key,
+ PINFCONTEXT ContextOut)
+{
+ return INF_SUCCESS(InfpFindFirstMatchLine(ContextIn, Key, ContextOut));
+}
+
+
+BOOLEAN
+InfFindNextMatchLine(PINFCONTEXT ContextIn,
+ PCWSTR Key,
+ PINFCONTEXT ContextOut)
+{
+ return INF_SUCCESS(InfpFindNextMatchLine(ContextIn, Key, ContextOut));
+}
+
+
+LONG
+InfGetLineCount(HINF InfHandle,
+ PCWSTR Section)
+{
+ return InfpGetLineCount(InfHandle, Section);
+}
+
+
+/* InfGetLineText */
+
+
+LONG
+InfGetFieldCount(PINFCONTEXT Context)
+{
+ return InfpGetFieldCount(Context);
+}
+
+
+BOOLEAN
+InfGetBinaryField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PUCHAR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return INF_SUCCESS(InfpGetBinaryField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetIntField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PLONG IntegerValue)
+{
+ return INF_SUCCESS(InfpGetIntField(Context, FieldIndex, IntegerValue));
+}
+
+
+BOOLEAN
+InfGetMultiSzField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return INF_SUCCESS(InfpGetMultiSzField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetStringField(PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWSTR ReturnBuffer,
+ ULONG ReturnBufferSize,
+ PULONG RequiredSize)
+{
+ return INF_SUCCESS(InfpGetStringField(Context, FieldIndex, ReturnBuffer,
+ ReturnBufferSize, RequiredSize));
+}
+
+
+BOOLEAN
+InfGetData(PINFCONTEXT Context,
+ PWCHAR *Key,
+ PWCHAR *Data)
+{
+ return INF_SUCCESS(InfpGetData(Context, Key, Data));
+}
+
+
+BOOLEAN
+InfGetDataField (PINFCONTEXT Context,
+ ULONG FieldIndex,
+ PWCHAR *Data)
+{
+ return INF_SUCCESS(InfpGetDataField(Context, FieldIndex, Data));
+}
+
+VOID
+InfFreeContext(PINFCONTEXT Context)
+{
+ InfpFreeContext(Context);
+}
+
+/* EOF */
LIB_BASE_ = $(LIB_BASE)$(SEP)\r
\r
include $(LIB_BASE_)zlib/zlib.mak\r
+include $(LIB_BASE_)inflib/inflib.mak\r