/*
- * 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>
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
*/
#ifdef INFLIB_HOST
/* Definitions native to the host on which we're building */
+#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#include <errno.h>
+#define FALSE 0
+#define TRUE 1
+
#define FREE(Area) free(Area)
#define MALLOC(Size) malloc(Size)
#define ZEROMEMORY(Area, Size) memset((Area), '\0', (Size))
#define _tcscpy strcpy
#define _tcstoul strtoul
#define _tcstol strtol
+#define STRFMT "%s"
extern void DbgPrint(const char *Fmt, ...);
#define INF_STATUS_BUFFER_OVERFLOW STATUS_BUFFER_OVERFLOW
#define INF_SUCCESS(x) (0 <= (x))
+#define STRFMT "%S"
+
#endif /* INFLIB_HOST */
typedef const TCHAR *PCTSTR;
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
#ifndef INFCOMMON_H_INCLUDED
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
/* PRIVATE FUNCTIONS ********************************************************/
static PINFCACHELINE
-InfpCacheFreeLine (PINFCACHELINE Line)
+InfpFreeLine (PINFCACHELINE Line)
{
PINFCACHELINE Next;
PINFCACHEFIELD Field;
PINFCACHESECTION
-InfpCacheFreeSection (PINFCACHESECTION Section)
+InfpFreeSection (PINFCACHESECTION Section)
{
PINFCACHESECTION Next;
Next = Section->Next;
while (Section->FirstLine != NULL)
{
- Section->FirstLine = InfpCacheFreeLine (Section->FirstLine);
+ Section->FirstLine = InfpFreeLine (Section->FirstLine);
}
Section->LastLine = NULL;
}
-static PINFCACHESECTION
-InfpCacheFindSection (PINFCACHE Cache,
- PCTSTR Name)
+PINFCACHESECTION
+InfpFindSection(PINFCACHE Cache,
+ PCTSTR Name)
{
PINFCACHESECTION Section = NULL;
while (Section != NULL)
{
if (_tcsicmp (Section->Name, Name) == 0)
- {
- return Section;
- }
+ {
+ return Section;
+ }
/* get the next section*/
Section = Section->Next;
}
-static PINFCACHESECTION
-InfpCacheAddSection (PINFCACHE Cache,
- PTCHAR Name)
+PINFCACHESECTION
+InfpAddSection(PINFCACHE Cache,
+ PCTSTR Name)
{
PINFCACHESECTION Section = NULL;
ULONG Size;
}
-static PINFCACHELINE
-InfpCacheAddLine (PINFCACHESECTION Section)
+PINFCACHELINE
+InfpAddLine(PINFCACHESECTION Section)
{
PINFCACHELINE Line;
}
-static PVOID
-InfpAddKeyToLine (PINFCACHELINE Line,
- PTCHAR Key)
+PVOID
+InfpAddKeyToLine(PINFCACHELINE Line,
+ PCTSTR Key)
{
if (Line == NULL)
- return NULL;
+ {
+ DPRINT1("Invalid Line\n");
+ return NULL;
+ }
if (Line->Key != NULL)
- return NULL;
+ {
+ DPRINT1("Line already has a key\n");
+ return NULL;
+ }
- Line->Key = (PTCHAR)MALLOC ((_tcslen (Key) + 1) * sizeof(TCHAR));
+ Line->Key = (PTCHAR)MALLOC((_tcslen(Key) + 1) * sizeof(TCHAR));
if (Line->Key == NULL)
- return NULL;
+ {
+ DPRINT1("MALLOC() failed\n");
+ return NULL;
+ }
- _tcscpy (Line->Key, Key);
+ _tcscpy(Line->Key, Key);
return (PVOID)Line->Key;
}
-static PVOID
-InfpAddFieldToLine (PINFCACHELINE Line,
- PTCHAR Data)
+PVOID
+InfpAddFieldToLine(PINFCACHELINE Line,
+ PCTSTR Data)
{
PINFCACHEFIELD Field;
ULONG Size;
Size = sizeof(INFCACHEFIELD) + (_tcslen(Data) * sizeof(TCHAR));
- Field = (PINFCACHEFIELD)MALLOC (Size);
+ Field = (PINFCACHEFIELD)MALLOC(Size);
if (Field == NULL)
{
+ DPRINT1("MALLOC() failed\n");
return NULL;
}
ZEROMEMORY (Field,
PINFCACHELINE
-InfpCacheFindKeyLine (PINFCACHESECTION Section,
- PTCHAR Key)
+InfpFindKeyLine(PINFCACHESECTION Section,
+ PCTSTR Key)
{
PINFCACHELINE Line;
while (Line != NULL)
{
if (Line->Key != NULL && _tcsicmp (Line->Key, Key) == 0)
- {
- return Line;
- }
+ {
+ return Line;
+ }
Line = Line->Next;
}
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'));
+ *ptr == CONTROL_Z ||
+ *ptr == '\n' ||
+ (*ptr == '\r' && *(ptr + 1) == '\n'));
}
return NULL;
}
- Section = InfpCacheFindSection (parser->file,
- parser->token);
+ Section = InfpFindSection(parser->file,
+ parser->token);
if (Section == NULL)
{
/* need to create a new one */
- Section= InfpCacheAddSection (parser->file,
- parser->token);
+ Section= InfpAddSection(parser->file,
+ parser->token);
if (Section == NULL)
- {
- parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
- return NULL;
- }
+ {
+ parser->error = INF_STATUS_NOT_ENOUGH_MEMORY;
+ return NULL;
+ }
}
parser->token_len = 0;
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->error = INF_STATUS_WRONG_INF_STYLE;
+ return NULL;
+ }
- parser->line = InfpCacheAddLine (parser->cur_section);
+ parser->line = InfpAddLine(parser->cur_section);
if (parser->line == NULL)
- goto error;
+ goto error;
}
else
{
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;
- }
+ {
+ 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;
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;
- }
+ {
+ 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;
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;
- }
+ {
+ 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 );
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;
- }
- }
+ {
+ 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 );
for (p = pos; !is_eol( parser, p ); p++)
{
if (*p == '\\')
- {
- parser->start = p;
- set_state( parser, EOL_BACKSLASH );
- return p;
- }
+ {
+ parser->start = p;
+ set_state( parser, EOL_BACKSLASH );
+ return p;
+ }
if (!isspace(*p))
- break;
+ break;
}
parser->start = p;
pop_state( parser );
for (p = pos; !is_eol( parser, p ); p++)
{
if (*p == '\\')
- {
- set_state( parser, EOL_BACKSLASH );
- return p;
- }
+ {
+ set_state( parser, EOL_BACKSLASH );
+ return p;
+ }
if (!isspace(*p))
- break;
+ break;
}
pop_state( parser );
return p;
/* parse a complete buffer */
INFSTATUS
InfpParseBuffer (PINFCACHE file,
- const CHAR *buffer,
- const CHAR *end,
- PULONG error_line)
+ const CHAR *buffer,
+ const CHAR *end,
+ PULONG error_line)
{
struct parser parser;
const CHAR *pos = buffer;
if (parser.error)
{
if (error_line)
- *error_line = parser.line_pos;
+ *error_line = parser.line_pos;
return parser.error;
}
/* find the [strings] section */
- file->StringsSection = InfpCacheFindSection (file,
- _T("Strings"));
+ file->StringsSection = InfpFindSection(file,
+ _T("Strings"));
return INF_STATUS_SUCCESS;
}
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
INFSTATUS
-InfpFindFirstLine(HINF InfHandle,
+InfpFindFirstLine(PINFCACHE Cache,
PCTSTR Section,
PCTSTR Key,
PINFCONTEXT *Context)
{
- PINFCACHE Cache;
PINFCACHESECTION CacheSection;
PINFCACHELINE CacheLine;
- if (InfHandle == NULL || Section == NULL || Context == NULL)
+ if (Cache == NULL || Section == NULL || Context == NULL)
{
- DPRINT("Invalid parameter\n");
+ DPRINT1("Invalid parameter\n");
return INF_STATUS_INVALID_PARAMETER;
}
- *Context = MALLOC(sizeof(INFCONTEXT));
- if (NULL == *Context)
+ CacheSection = InfpFindSection(Cache, Section);
+ if (NULL == CacheSection)
{
- DPRINT1("MALLOC() failed\n");
- return INF_STATUS_NO_MEMORY;
+ DPRINT("Section not found\n");
+ return INF_STATUS_NOT_FOUND;
}
- Cache = (PINFCACHE)InfHandle;
-
- /* Iterate through list of sections */
- CacheSection = Cache->FirstSection;
- while (CacheSection != NULL)
+ if (Key != 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;
- }
+ CacheLine = InfpFindKeyLine(CacheSection, Key);
+ }
+ else
+ {
+ CacheLine = CacheSection->FirstLine;
+ }
- /* Get the next section */
- CacheSection = CacheSection->Next;
+ if (NULL == CacheLine)
+ {
+ DPRINT("Key not found\n");
+ return INF_STATUS_NOT_FOUND;
}
- DPRINT("Section not found\n");
+ *Context = MALLOC(sizeof(INFCONTEXT));
+ if (NULL == *Context)
+ {
+ DPRINT1("MALLOC() failed\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+ (*Context)->Inf = (PVOID)Cache;
+ (*Context)->Section = (PVOID)CacheSection;
+ (*Context)->Line = (PVOID)CacheLine;
- return INF_STATUS_NOT_FOUND;
+ return INF_STATUS_SUCCESS;
}
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
#ifndef INFHOST_H_INCLUDED
#define INFHOST_H_INCLUDED
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <infcommon.h>
extern int InfHostOpenBufferedFile(PHINF InfHandle,
unsigned long BufferSize,
unsigned long *ErrorLine);
extern int InfHostOpenFile(PHINF InfHandle,
- char *FileName,
+ const char *FileName,
unsigned long *ErrorLine);
+extern int InfHostWriteFile(HINF InfHandle,
+ const char *FileName,
+ const char *HeaderComment);
extern void InfHostCloseFile(HINF InfHandle);
extern int InfHostFindFirstLine(HINF InfHandle,
const char *Section,
extern int InfHostGetDataField(PINFCONTEXT Context,
unsigned long FieldIndex,
char **Data);
-extern VOID InfHostFreeContext(PINFCONTEXT Context);
+extern int InfHostFindOrAddSection(HINF InfHandle,
+ const char *Section,
+ PINFCONTEXT *Context);
+extern int InfHostAddLine(PINFCONTEXT Context, const char *Key);
+extern int InfHostAddField(PINFCONTEXT Context, const char *Data);
+extern void InfHostFreeContext(PINFCONTEXT Context);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
#endif /* INFROS_H_INCLUDED */
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
-#include <stdio.h>
-#include <errno.h>
#include "inflib.h"
#include "infhost.h"
Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
if (Cache == NULL)
{
- DPRINT("MALLOC() failed\n");
+ DPRINT1("MALLOC() failed\n");
FREE(FileBuffer);
return(INF_STATUS_INSUFFICIENT_RESOURCES);
}
int
InfHostOpenFile(PHINF InfHandle,
- char *FileName,
+ const char *FileName,
unsigned long *ErrorLine)
{
FILE *File;
File = fopen(FileName, "rb");
if (NULL == File)
{
- DPRINT("fopen() failed (errno %d)\n", errno);
+ DPRINT1("fopen() failed (errno %d)\n", errno);
return -1;
}
/* Query file size */
if (fseek(File, 0, SEEK_END))
{
- DPRINT("fseek() to EOF failed (errno %d)\n", errno);
+ DPRINT1("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);
+ DPRINT1("ftell() failed (errno %d)\n", errno);
fclose(File);
return -1;
}
/* Rewind */
if (fseek(File, 0, SEEK_SET))
{
- DPRINT("fseek() to BOF failed (errno %d)\n", errno);
+ DPRINT1("fseek() to BOF failed (errno %d)\n", errno);
fclose(File);
return -1;
}
/* Read file */
if (FileLength != fread(FileBuffer, 1, FileLength, File))
{
- DPRINT("fread() failed (errno %d)\n", errno);
+ DPRINT1("fread() failed (errno %d)\n", errno);
fclose(File);
return -1;
}
Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE));
if (Cache == NULL)
{
- DPRINT("MALLOC() failed\n");
+ DPRINT1("MALLOC() failed\n");
FREE(FileBuffer);
return -1;
}
while (Cache->FirstSection != NULL)
{
- Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
+ Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
}
Cache->LastSection = 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
-#include <errno.h>
#include "inflib.h"
#include "infhost.h"
--- /dev/null
+/*
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+void
+DbgPrint(const char *Fmt, ...)
+{
+ va_list Args;
+
+ va_start(Args, Fmt);
+ vfprintf(stderr, Fmt, Args);
+ va_end(Args);
+}
+
+/* EOF */
--- /dev/null
+/*
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infhost.h"
+
+#define NDEBUG
+#include <debug.h>
+
+int
+InfHostWriteFile(HINF InfHandle, const char *FileName,
+ const char *HeaderComment)
+{
+ char *Buffer;
+ unsigned long BufferSize;
+ INFSTATUS Status;
+ FILE *File;
+
+ Status = InfpBuildFileBuffer((PINFCACHE) InfHandle, &Buffer, &BufferSize);
+ if (! INF_SUCCESS(Status))
+ {
+ errno = Status;
+ return -1;
+ }
+
+ File = fopen(FileName, "wb");
+ if (NULL == File)
+ {
+ FREE(Buffer);
+ DPRINT1("fopen() failed (errno %d)\n", errno);
+ return -1;
+ }
+
+ DPRINT("fopen() successful\n");
+
+ if (NULL != HeaderComment && '\0' != *HeaderComment)
+ {
+ fprintf(File, "; %s\r\n\r\n", HeaderComment);
+ }
+
+ if (BufferSize != fwrite(Buffer, 1, BufferSize, File))
+ {
+ DPRINT1("fwrite() failed (errno %d)\n", errno);
+ fclose(File);
+ FREE(Buffer);
+ return -1;
+ }
+
+ fclose(File);
+
+ FREE(Buffer);
+
+ return 0;
+}
+
+int
+InfHostFindOrAddSection(HINF InfHandle,
+ const char *Section,
+ PINFCONTEXT *Context)
+{
+ INFSTATUS Status;
+
+ Status = InfpFindOrAddSection((PINFCACHE) InfHandle, Section, Context);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+int
+InfHostAddLine(PINFCONTEXT Context, const char *Key)
+{
+ INFSTATUS Status;
+
+ Status = InfpAddLineWithKey(Context, Key);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+int
+InfHostAddField(PINFCONTEXT Context, const char *Data)
+{
+ INFSTATUS Status;
+
+ Status = InfpAddField(Context, Data);
+ if (INF_SUCCESS(Status))
+ {
+ return 0;
+ }
+ else
+ {
+ errno = Status;
+ return -1;
+ }
+}
+
+/* EOF */
/*
- * 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>
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
*/
#include <ctype.h>
INFLIB_HOST_SOURCES = $(addprefix $(INFLIB_BASE_), \
infcore.c \
infget.c \
+ infput.c \
infhostgen.c \
infhostget.c \
+ infhostglue.c \
+ infhostput.c \
)
INFLIB_HOST_OBJECTS = \
INFLIB_HOST_CFLAGS = -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes -DINFLIB_HOST -D_M_IX86 \
- -I$(INFLIB_BASE) -Iinclude/reactos
+ -I$(INFLIB_BASE) -Iinclude/reactos -DDBG
$(INFLIB_HOST_TARGET): $(INFLIB_HOST_OBJECTS) | $(INFLIB_OUT)
$(ECHO_AR)
$(ECHO_CC)
${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+$(INFLIB_INT_)infput.o: $(INFLIB_BASE_)infput.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 $@
$(ECHO_CC)
${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+$(INFLIB_INT_)infhostglue.o: $(INFLIB_BASE_)infhostglue.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
+$(INFLIB_INT_)infhostput.o: $(INFLIB_BASE_)infhostput.c | $(INFLIB_INT)
+ $(ECHO_CC)
+ ${host_gcc} $(INFLIB_HOST_CFLAGS) -c $< -o $@
+
.PHONY: inflib_host
inflib_host: $(INFLIB_HOST_TARGET)
<pch>inflib.h</pch>
<file>infcore.c</file>
<file>infget.c</file>
+ <file>infput.c</file>
<file>infrosgen.c</file>
<file>infrosget.c</file>
+ <file>infrosput.c</file>
</module>
/*
- * 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>
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
#ifndef INFPRIV_H_INCLUDED
#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;
LONG FieldCount;
- PTCHAR Key;
+ PTSTR Key;
PINFCACHEFIELD FirstField;
PINFCACHEFIELD LastField;
PINFCACHESECTION StringsSection;
} INFCACHE, *PINFCACHE;
+typedef struct _INFCONTEXT
+{
+ PINFCACHE Inf;
+ PINFCACHESECTION Section;
+ PINFCACHELINE Line;
+} INFCONTEXT;
+
typedef long INFSTATUS;
/* FUNCTIONS ****************************************************************/
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,
+extern PINFCACHESECTION InfpFreeSection(PINFCACHESECTION Section);
+extern PINFCACHESECTION InfpAddSection(PINFCACHE Cache,
+ PCTSTR Name);
+extern PINFCACHELINE InfpAddLine(PINFCACHESECTION Section);
+extern PVOID InfpAddKeyToLine(PINFCACHELINE Line,
+ PCTSTR Key);
+extern PVOID InfpAddFieldToLine(PINFCACHELINE Line,
+ PCTSTR Data);
+extern PINFCACHELINE InfpFindKeyLine(PINFCACHESECTION Section,
+ PCTSTR Key);
+extern PINFCACHESECTION InfpFindSection(PINFCACHE Cache,
+ PCTSTR Section);
+
+extern INFSTATUS InfpBuildFileBuffer(PINFCACHE InfHandle,
+ char **Buffer,
+ unsigned long *BufferSize);
+
+extern INFSTATUS InfpFindFirstLine(PINFCACHE InfHandle,
PCTSTR Section,
PCTSTR Key,
PINFCONTEXT *Context);
extern INFSTATUS InfpGetDataField(PINFCONTEXT Context,
ULONG FieldIndex,
PTCHAR *Data);
+
+extern INFSTATUS InfpFindOrAddSection(PINFCACHE Cache,
+ PCTSTR Section,
+ PINFCONTEXT *Context);
+extern INFSTATUS InfpAddLineWithKey(PINFCONTEXT Context, PCTSTR Key);
+extern INFSTATUS InfpAddField(PINFCONTEXT Context, PCTSTR Data);
+
extern VOID InfpFreeContext(PINFCONTEXT Context);
#endif /* INFPRIV_H_INCLUDED */
--- /dev/null
+/*
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define EOL _T("\r\n")
+#define SIZE_INC 1024
+
+typedef struct _OUTPUTBUFFER
+{
+ PCHAR Buffer;
+ PCHAR Current;
+ ULONG TotalSize;
+ ULONG FreeSize;
+ INFSTATUS Status;
+} OUTPUTBUFFER, *POUTPUTBUFFER;
+
+static void
+Output(POUTPUTBUFFER OutBuf, PCTSTR Text)
+{
+ ULONG Length;
+ PCHAR NewBuf;
+ ULONG NewSize;
+
+ /* Skip mode? */
+ if (! INF_SUCCESS(OutBuf->Status))
+ {
+ return;
+ }
+
+ /* Doesn't fit? */
+ Length = _tcslen(Text);
+ if (OutBuf->FreeSize < Length + 1 && INF_SUCCESS(OutBuf->Status))
+ {
+ DPRINT("Out of free space. TotalSize %lu FreeSize %lu Length %u\n",
+ OutBuf->TotalSize, OutBuf->FreeSize, Length);
+ /* Round up to next SIZE_INC */
+ NewSize = OutBuf->TotalSize +
+ (((Length + 1) - OutBuf->FreeSize + (SIZE_INC - 1)) /
+ SIZE_INC) * SIZE_INC;
+ DPRINT("NewSize %lu\n", NewSize);
+ NewBuf = MALLOC(NewSize);
+ /* Abort if failed */
+ if (NULL == NewBuf)
+ {
+ DPRINT1("MALLOC() failed\n");
+ OutBuf->Status = INF_STATUS_NO_MEMORY;
+ return;
+ }
+
+ /* Need to copy old contents? */
+ if (NULL != OutBuf->Buffer)
+ {
+ DPRINT("Copying %lu bytes from old content\n",
+ OutBuf->TotalSize - OutBuf->FreeSize);
+ MEMCPY(NewBuf, OutBuf->Buffer, OutBuf->TotalSize - OutBuf->FreeSize);
+ OutBuf->Current = NewBuf + (OutBuf->Current - OutBuf->Buffer);
+ FREE(OutBuf->Buffer);
+ }
+ else
+ {
+ OutBuf->Current = NewBuf;
+ }
+ OutBuf->Buffer = NewBuf;
+ OutBuf->FreeSize += NewSize - OutBuf->TotalSize;
+ OutBuf->TotalSize = NewSize;
+ DPRINT("After reallocation TotalSize %lu FreeSize %lu\n",
+ OutBuf->TotalSize, OutBuf->FreeSize);
+ }
+
+ /* We're guaranteed to have enough room now. Copy char by char because of
+ possible "conversion" from Unicode to Ansi */
+ while (Length--)
+ {
+ *OutBuf->Current++ = (char) *Text++;
+ OutBuf->FreeSize--;
+ }
+ OutBuf->Current[1] = '\0';
+}
+
+INFSTATUS
+InfpBuildFileBuffer(PINFCACHE Cache,
+ PCHAR *Buffer,
+ PULONG BufferSize)
+{
+ OUTPUTBUFFER OutBuf;
+ PINFCACHESECTION CacheSection;
+ PINFCACHELINE CacheLine;
+ PINFCACHEFIELD CacheField;
+ PTCHAR p;
+ BOOLEAN NeedQuotes;
+
+ OutBuf.Buffer = NULL;
+ OutBuf.Current = NULL;
+ OutBuf.FreeSize = 0;
+ OutBuf.TotalSize = 0;
+ OutBuf.Status = INF_STATUS_SUCCESS;
+
+ /* Iterate through list of sections */
+ CacheSection = Cache->FirstSection;
+ while (CacheSection != NULL)
+ {
+ DPRINT("Processing section " STRFMT "\n", CacheSection->Name);
+ if (CacheSection != Cache->FirstSection)
+ {
+ Output(&OutBuf, EOL);
+ }
+ Output(&OutBuf, _T("["));
+ Output(&OutBuf, CacheSection->Name);
+ Output(&OutBuf, _T("]"));
+ Output(&OutBuf, EOL);
+
+ /* Iterate through list of lines */
+ CacheLine = CacheSection->FirstLine;
+ while (CacheLine != NULL)
+ {
+ if (NULL != CacheLine->Key)
+ {
+ DPRINT("Line with key " STRFMT "\n", CacheLine->Key);
+ Output(&OutBuf, CacheLine->Key);
+ Output(&OutBuf, _T(" = "));
+ }
+ else
+ {
+ DPRINT("Line without key\n");
+ }
+
+ /* Iterate through list of lines */
+ CacheField = CacheLine->FirstField;
+ while (CacheField != NULL)
+ {
+ if (CacheField != CacheLine->FirstField)
+ {
+ Output(&OutBuf, _T(","));
+ }
+ p = CacheField->Data;
+ NeedQuotes = FALSE;
+ while (_T('\0') != *p && ! NeedQuotes)
+ {
+ NeedQuotes = _T(',') == *p || _T(';') == *p ||
+ _T('\\') == *p;
+ p++;
+ }
+ if (NeedQuotes)
+ {
+ Output(&OutBuf, _T("\""));
+ Output(&OutBuf, CacheField->Data);
+ Output(&OutBuf, _T("\""));
+ }
+ else
+ {
+ Output(&OutBuf, CacheField->Data);
+ }
+
+ /* Get the next field */
+ CacheField = CacheField->Next;
+ }
+
+ Output(&OutBuf, EOL);
+ /* Get the next line */
+ CacheLine = CacheLine->Next;
+ }
+
+ /* Get the next section */
+ CacheSection = CacheSection->Next;
+ }
+
+ if (INF_SUCCESS(OutBuf.Status))
+ {
+ *Buffer = OutBuf.Buffer;
+ *BufferSize = OutBuf.TotalSize - OutBuf.FreeSize;
+ }
+ else if (NULL != OutBuf.Buffer)
+ {
+ FREE(OutBuf.Buffer);
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpFindOrAddSection(PINFCACHE Cache,
+ PCTSTR Section,
+ PINFCONTEXT *Context)
+{
+ DPRINT("InfpFindOrAddSection section " STRFMT "\n", Section);
+
+ *Context = MALLOC(sizeof(INFCONTEXT));
+ if (NULL == *Context)
+ {
+ DPRINT1("MALLOC() failed\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+
+ (*Context)->Inf = Cache;
+ (*Context)->Section = InfpFindSection(Cache, Section);
+ (*Context)->Line = NULL;
+ if (NULL == (*Context)->Section)
+ {
+ DPRINT("Section not found, creating it\n");
+ (*Context)->Section = InfpAddSection(Cache, Section);
+ if (NULL == (*Context)->Section)
+ {
+ DPRINT("Failed to create section\n");
+ FREE(*Context);
+ return INF_STATUS_NO_MEMORY;
+ }
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpAddLineWithKey(PINFCONTEXT Context, PCTSTR Key)
+{
+ if (NULL == Context)
+ {
+ DPRINT1("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ Context->Line = InfpAddLine(Context->Section);
+ if (NULL == Context->Line)
+ {
+ DPRINT("Failed to create line\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+
+ if (NULL != Key && NULL == InfpAddKeyToLine(Context->Line, Key))
+ {
+ DPRINT("Failed to add key\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+INFSTATUS
+InfpAddField(PINFCONTEXT Context, PCTSTR Data)
+{
+ if (NULL == Context || NULL == Context->Line)
+ {
+ DPRINT1("Invalid parameter\n");
+ return INF_STATUS_INVALID_PARAMETER;
+ }
+
+ if (NULL == InfpAddFieldToLine(Context->Line, Data))
+ {
+ DPRINT("Failed to add field\n");
+ return INF_STATUS_NO_MEMORY;
+ }
+
+ return INF_STATUS_SUCCESS;
+}
+
+/* EOF */
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
#ifndef INFROS_H_INCLUDED
#define INFROS_H_INCLUDED
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <infcommon.h>
extern VOID InfSetHeap(PVOID Heap);
extern NTSTATUS InfOpenFile(PHINF InfHandle,
PUNICODE_STRING FileName,
PULONG ErrorLine);
+extern NTSTATUS InfWriteFile(HINF InfHandle,
+ PUNICODE_STRING FileName,
+ PUNICODE_STRING HeaderComment);
extern VOID InfCloseFile(HINF InfHandle);
extern BOOLEAN InfFindFirstLine(HINF InfHandle,
PCWSTR Section,
extern BOOLEAN InfGetDataField(PINFCONTEXT Context,
ULONG FieldIndex,
PWCHAR *Data);
+extern BOOLEAN InfFindOrAddSection(HINF InfHandle,
+ PCWSTR Section,
+ PINFCONTEXT *Context);
+extern BOOLEAN InfAddLine(PINFCONTEXT Context, PCWSTR Key);
+extern BOOLEAN InfAddField(PINFCONTEXT Context, PCWSTR Data);
extern VOID InfFreeContext(PINFCONTEXT Context);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif /* INFROS_H_INCLUDED */
/* EOF */
/*
- * 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
while (Cache->FirstSection != NULL)
{
- Cache->FirstSection = InfpCacheFreeSection(Cache->FirstSection);
+ Cache->FirstSection = InfpFreeSection(Cache->FirstSection);
}
Cache->LastSection = 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
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * PROGRAMMER: Royce Mitchell III
+ * Eric Kohl
+ * Ge van Geldorp <gvg@reactos.org>
*/
/* INCLUDES *****************************************************************/
--- /dev/null
+/*
+ * PROJECT: .inf file parser
+ * LICENSE: GPL - See COPYING in the top level directory
+ * COPYRIGHT: Copyright 2005 Ge van Geldorp <gvg@reactos.org>
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include "inflib.h"
+#include "infros.h"
+
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+InfWriteFile(HINF InfHandle,
+ PUNICODE_STRING FileName,
+ PUNICODE_STRING HeaderComment)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+ INFSTATUS InfStatus;
+ PCHAR Buffer;
+ ULONG BufferSize;
+ PCHAR HeaderBuffer;
+ ULONG HeaderBufferSize;
+ UINT Index;
+
+ InfStatus = InfpBuildFileBuffer((PINFCACHE) InfHandle, &Buffer, &BufferSize);
+ if (! INF_SUCCESS(InfStatus))
+ {
+ DPRINT("Failed to create buffer (Status 0x%lx)\n", InfStatus);
+ return InfStatus;
+ }
+
+ /* Open the inf file */
+ InitializeObjectAttributes(&ObjectAttributes,
+ FileName,
+ 0,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ GENERIC_WRITE | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ 0,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (!INF_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
+ FREE(Buffer);
+ return Status;
+ }
+
+ DPRINT("NtOpenFile() successful\n");
+
+ if (NULL != HeaderComment && 0 != HeaderComment->Length)
+ {
+ /* This is just a comment header, don't abort on errors here */
+ HeaderBufferSize = HeaderComment->Length / sizeof(WCHAR) + 7;
+ HeaderBuffer = MALLOC(HeaderBufferSize);
+ if (NULL != HeaderBuffer)
+ {
+ strcpy(HeaderBuffer, "; ");
+ for (Index = 0; Index < HeaderComment->Length / sizeof(WCHAR); Index++)
+ {
+ HeaderBuffer[2 + Index] = (CHAR) HeaderComment->Buffer[Index];
+ }
+ strcpy(HeaderBuffer + (2 + HeaderComment->Length / sizeof(WCHAR)),
+ "\r\n\r\n");
+ NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ HeaderBuffer,
+ HeaderBufferSize,
+ NULL,
+ NULL);
+ FREE(HeaderBuffer);
+ }
+ }
+
+ /* Write main contents */
+ Status = NtWriteFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ Buffer,
+ BufferSize,
+ NULL,
+ NULL);
+
+ NtClose(FileHandle);
+ FREE(Buffer);
+
+ if (!INF_SUCCESS(Status))
+ {
+ DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
+ FREE(Buffer);
+ return(Status);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN
+InfFindOrAddSection(HINF InfHandle,
+ PCWSTR Section,
+ PINFCONTEXT *Context)
+{
+ return INF_SUCCESS(InfpFindOrAddSection((PINFCACHE) InfHandle,
+ Section, Context));
+}
+
+BOOLEAN
+InfHostAddLine(PINFCONTEXT Context, PCWSTR Key)
+{
+ return INF_SUCCESS(InfpAddLineWithKey(Context, Key));
+}
+
+BOOLEAN
+InfHostAddField(PINFCONTEXT Context, PCWSTR Data)
+{
+ return INF_SUCCESS(InfpAddField(Context, Data));
+}
+
+/* EOF */