diff --git a/freeldr/freeldr/CHANGELOG b/freeldr/freeldr/CHANGELOG index b1ec4b223a2..701cde5e52e 100644 --- a/freeldr/freeldr/CHANGELOG +++ b/freeldr/freeldr/CHANGELOG @@ -1,3 +1,9 @@ +Changes in v1.8.12 (5/25/2003) (ekohl) + +- Added .inf-file parser +- SetupLdr loads and uses txtsetup.sif +- Removed .hiv (text-hive) parser + Changes in v1.8.11 (4/30/2003) (ekohl) - Added DiskGetExtendedDriveParameters() diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 2ca3864d15a..18dd30621cd 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -233,9 +233,7 @@ UI_OBJS = tui.o \ ui.o \ gui.o -REACTOS_OBJS= reactos.o \ - arcname.o \ - reghive.o \ +REACTOS_OBJS= arcname.o \ binhive.o \ registry.o @@ -255,6 +253,8 @@ INIFILE_OBJS= inifile.o \ ini_init.o \ parse.o +INFFILE_OBJS= inffile.o + VIDEO_OBJS = video.o \ vidmode.o \ fade.o \ @@ -269,17 +269,19 @@ MATH_OBJS = libgcc2.o BASE_OBJS = freeldr.o \ debug.o \ - drivemap.o \ multiboot.o \ version.o FREELDR_OBJS= bootmgr.o \ + drivemap.o \ miscboot.o \ options.o \ linuxboot.o \ oslist.o \ custom.o +ROSLDR_OBJS = reactos.o + SETUPLDR_OBJS= setupldr.o COMMON_OBJS = $(ARCH_OBJS) \ @@ -291,23 +293,33 @@ COMMON_OBJS = $(ARCH_OBJS) \ $(DISK_OBJS) \ $(MM_OBJS) \ $(CACHE_OBJS) \ - $(INIFILE_OBJS) \ $(VIDEO_OBJS) \ $(MATH_OBJS) \ $(BASE_OBJS) +SPECIAL_OBJS = $(INIFILE_OBJS) \ + $(INFFILE_OBJS) \ + $(FREELDR_OBJS) \ + $(ROSLDR_OBJS) \ + $(SETUPLDR_OBJS) + + F_OBJS = $(COMMON_OBJS) \ + $(INIFILE_OBJS) \ + $(ROSLDR_OBJS) \ $(FREELDR_OBJS) S_OBJS = $(COMMON_OBJS) \ + $(INIFILE_OBJS) \ + $(INFFILE_OBJS) \ $(SETUPLDR_OBJS) + ############################################# # ALL THE OBJECTS # ALL_OBJS = $(COMMON_OBJS) \ - $(FREELDR_OBJS) \ - $(SETUPLDR_OBJS) + $(SPECIAL_OBJS) ############################################# @@ -324,6 +336,7 @@ VPATH = $(SRCDIR)/ \ $(SRCDIR)/mm \ $(SRCDIR)/cache \ $(SRCDIR)/inifile \ + $(SRCDIR)/inffile \ $(SRCDIR)/video \ $(SRCDIR)/math \ $(SRCDIR)/include @@ -347,7 +360,6 @@ freeldr.sys : $(ALL_OBJS) setupldr.sys : $(ALL_OBJS) @echo ===================================================== LINKING $@ -# @$(LD) -N -Ttext=0x8000 --oformat=binary -s -o setupldr.sys $(S_OBJS) @$(LD) $(LFLAGS) -Map setupldr.map -o setupldr.exe $(S_OBJS) @$(NM) --numeric-sort setupldr.exe > setupldr.sym @$(OBJCOPY) -O binary setupldr.exe setupldr.sys diff --git a/freeldr/freeldr/include/inffile.h b/freeldr/freeldr/include/inffile.h new file mode 100644 index 00000000000..aa33414ec92 --- /dev/null +++ b/freeldr/freeldr/include/inffile.h @@ -0,0 +1,130 @@ +/* + * ReactOS kernel + * Copyright (C) 2002, 2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: inffile.h,v 1.1 2003/05/25 21:17:30 ekohl Exp $ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/infcache.h + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +#ifndef __INFCACHE_H__ +#define __INFCACHE_H__ + + +#define STATUS_BAD_SECTION_NAME_LINE (0xC0700001) +#define STATUS_SECTION_NAME_TOO_LONG (0xC0700002) +#define STATUS_WRONG_INF_STYLE (0xC0700003) +#define STATUS_NOT_ENOUGH_MEMORY (0xC0700004) + +#define MAX_INF_STRING_LENGTH 512 + +typedef PU32 HINF, *PHINF; + +typedef struct _INFCONTEXT +{ + PVOID Inf; +// PVOID CurrentInf; + PVOID Section; + PVOID Line; +} INFCONTEXT, *PINFCONTEXT; + + +/* FUNCTIONS ****************************************************************/ + +BOOLEAN +InfOpenFile (PHINF InfHandle, + PCHAR FileName, + PU32 ErrorLine); + +VOID +InfCloseFile (HINF InfHandle); + + +BOOLEAN +InfFindFirstLine (HINF InfHandle, + PCHAR Section, + PCHAR Key, + PINFCONTEXT Context); + +BOOLEAN +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut); + +BOOLEAN +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut); + +BOOLEAN +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut); + + +S32 +InfGetLineCount (HINF InfHandle, + PCHAR Section); + +S32 +InfGetFieldCount (PINFCONTEXT Context); + + +BOOLEAN +InfGetBinaryField (PINFCONTEXT Context, + U32 FieldIndex, + PU8 ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize); + +BOOLEAN +InfGetIntField (PINFCONTEXT Context, + U32 FieldIndex, + S32 *IntegerValue); + +BOOLEAN +InfGetMultiSzField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize); + +BOOLEAN +InfGetStringField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize); + + + +BOOLEAN +InfGetData (PINFCONTEXT Context, + PCHAR *Key, + PCHAR *Data); + +BOOLEAN +InfGetDataField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR *Data); + +#endif /* __INFCACHE_H__ */ + +/* EOF */ diff --git a/freeldr/freeldr/include/version.h b/freeldr/freeldr/include/version.h index 0b942e9a08b..964948e93cc 100644 --- a/freeldr/freeldr/include/version.h +++ b/freeldr/freeldr/include/version.h @@ -22,7 +22,7 @@ /* just some stuff */ -#define VERSION "FreeLoader v1.8.11" +#define VERSION "FreeLoader v1.8.12" #define COPYRIGHT "Copyright (C) 1998-2003 Brian Palmer " #define AUTHOR_EMAIL "" #define BY_AUTHOR "by Brian Palmer" @@ -36,7 +36,7 @@ // #define FREELOADER_MAJOR_VERSION 1 #define FREELOADER_MINOR_VERSION 8 -#define FREELOADER_PATCH_VERSION 11 +#define FREELOADER_PATCH_VERSION 12 PUCHAR GetFreeLoaderVersionString(VOID); diff --git a/freeldr/freeldr/inffile/inffile.c b/freeldr/freeldr/inffile/inffile.c new file mode 100644 index 00000000000..4e54b063ad5 --- /dev/null +++ b/freeldr/freeldr/inffile/inffile.c @@ -0,0 +1,1494 @@ +/* + * ReactOS kernel + * Copyright (C) 2002,2003 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $Id: inffile.c,v 1.1 2003/05/25 21:18:16 ekohl Exp $ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS text-mode setup + * FILE: subsys/system/usetup/infcache.c + * PURPOSE: INF file parser that caches contents of INF file in memory + * PROGRAMMER: Royce Mitchell III + * Eric Kohl + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include +#include + +#include + + +#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) + + +typedef struct _INFCACHEFIELD +{ + struct _INFCACHEFIELD *Next; + struct _INFCACHEFIELD *Prev; + + CHAR Data[1]; +} INFCACHEFIELD, *PINFCACHEFIELD; + + +typedef struct _INFCACHELINE +{ + struct _INFCACHELINE *Next; + struct _INFCACHELINE *Prev; + + S32 FieldCount; + + PCHAR Key; + + PINFCACHEFIELD FirstField; + PINFCACHEFIELD LastField; + +} INFCACHELINE, *PINFCACHELINE; + + +typedef struct _INFCACHESECTION +{ + struct _INFCACHESECTION *Next; + struct _INFCACHESECTION *Prev; + + PINFCACHELINE FirstLine; + PINFCACHELINE LastLine; + + S32 LineCount; + + CHAR Name[1]; +} INFCACHESECTION, *PINFCACHESECTION; + + +typedef struct _INFCACHE +{ + PINFCACHESECTION FirstSection; + PINFCACHESECTION LastSection; + + PINFCACHESECTION StringsSection; +} INFCACHE, *PINFCACHE; + + +/* 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 */ + CHAR 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) + { + MmFreeMemory (Line->Key); + Line->Key = NULL; + } + + /* Remove data fields */ + while (Line->FirstField != NULL) + { + Field = Line->FirstField->Next; + MmFreeMemory (Line->FirstField); + Line->FirstField = Field; + } + Line->LastField = NULL; + + MmFreeMemory (Line); + + return Next; +} + + +static 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; + + MmFreeMemory (Section); + + return Next; +} + + +static PINFCACHESECTION +InfpCacheFindSection (PINFCACHE Cache, + PCHAR Name) +{ + PINFCACHESECTION Section = NULL; + + if (Cache == NULL || Name == NULL) + { + return NULL; + } + + /* iterate through list of sections */ + Section = Cache->FirstSection; + while (Section != NULL) + { + if (stricmp (Section->Name, Name) == 0) + { + return Section; + } + + /* get the next section*/ + Section = Section->Next; + } + + return NULL; +} + + +static PINFCACHESECTION +InfpCacheAddSection (PINFCACHE Cache, + PCHAR Name) +{ + PINFCACHESECTION Section = NULL; + U32 Size; + + if (Cache == NULL || Name == NULL) + { +// DPRINT("Invalid parameter\n"); + return NULL; + } + + /* Allocate and initialize the new section */ + Size = sizeof(INFCACHESECTION) + strlen (Name); + Section = (PINFCACHESECTION)MmAllocateMemory (Size); + if (Section == NULL) + { +// DPRINT("RtlAllocateHeap() failed\n"); + return NULL; + } + memset (Section, 0, Size); + + /* Copy section name */ + strcpy (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)MmAllocateMemory (sizeof(INFCACHELINE)); + if (Line == NULL) + { +// DPRINT("RtlAllocateHeap() failed\n"); + return NULL; + } + memset (Line, 0, 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, + PCHAR Key) +{ + if (Line == NULL) + return NULL; + + if (Line->Key != NULL) + return NULL; + + Line->Key = (PCHAR)MmAllocateMemory (strlen (Key) + 1); + if (Line->Key == NULL) + return NULL; + + strcpy (Line->Key, Key); + + return (PVOID)Line->Key; +} + + +static PVOID +InfpAddFieldToLine (PINFCACHELINE Line, + PCHAR Data) +{ + PINFCACHEFIELD Field; + U32 Size; + + Size = sizeof(INFCACHEFIELD) + strlen(Data); + Field = (PINFCACHEFIELD)MmAllocateMemory (Size); + if (Field == NULL) + { + return NULL; + } + memset (Field, 0, Size); + + strcpy (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; +} + + +static PINFCACHELINE +InfpCacheFindKeyLine (PINFCACHESECTION Section, + PCHAR Key) +{ + PINFCACHELINE Line; + + Line = Section->FirstLine; + while (Line != NULL) + { + if (Line->Key != NULL && stricmp (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 ) +{ + int len = pos - parser->start; + const CHAR *src = parser->start; + CHAR *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 ? (CHAR)*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 = FALSE; + 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 = FALSE; + 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 = 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 = FALSE; + 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 = 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 */ +static BOOLEAN +InfpParseBuffer (PINFCACHE file, + const CHAR *buffer, + const CHAR *end, + PU32 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 = TRUE; + 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, "Strings"); + + return TRUE; +} + +/* PUBLIC FUNCTIONS *********************************************************/ + +BOOLEAN +InfOpenFile(PHINF InfHandle, + PCHAR FileName, + PU32 ErrorLine) +{ + PFILE FileHandle; + PCHAR FileBuffer; + U32 FileSize; + PINFCACHE Cache; + BOOLEAN Success; + + + *InfHandle = NULL; + *ErrorLine = (U32)-1; + + + /* Open the inf file */ + FileHandle = FsOpenFile (FileName); + if (FileHandle == NULL) + { +// DPRINT("NtOpenFile() failed (Status %lx)\n", Status); + return FALSE; + } + +// DPRINT("NtOpenFile() successful\n"); + + /* Query file size */ + FileSize = FsGetFileSize (FileHandle); + if (FileSize == 0) + { +// DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); + FsCloseFile (FileHandle); + return FALSE; + } + +// DPRINT("File size: %lu\n", FileLength); + + /* Allocate file buffer */ + FileBuffer = MmAllocateMemory (FileSize + 1); + if (FileBuffer == NULL) + { +// DPRINT1("RtlAllocateHeap() failed\n"); + FsCloseFile (FileHandle); + return FALSE; + } + + /* Read file */ + Success = FsReadFile(FileHandle, FileSize, NULL, FileBuffer); + + FsCloseFile (FileHandle); + if (!Success) + { +// DPRINT("FsReadFile() failed\n"); + MmFreeMemory (FileBuffer); + return FALSE; + } + + /* Append string terminator */ + FileBuffer[FileSize] = 0; + + /* Allocate infcache header */ + Cache = (PINFCACHE)MmAllocateMemory (sizeof(INFCACHE)); + if (Cache == NULL) + { +// DPRINT("RtlAllocateHeap() failed\n"); + MmFreeMemory (FileBuffer); + return FALSE; + } + + /* Initialize inicache header */ + RtlZeroMemory(Cache, + sizeof(INFCACHE)); + + /* Parse the inf buffer */ + Success = InfpParseBuffer (Cache, + FileBuffer, + FileBuffer + FileSize, + ErrorLine); + if (!Success) + { + MmFreeMemory (Cache); + Cache = NULL; + } + + /* Free file buffer */ + MmFreeMemory (FileBuffer); + + *InfHandle = (HINF)Cache; + + return Success; +} + + +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; + + MmFreeMemory(Cache); +} + + +BOOLEAN +InfFindFirstLine (HINF InfHandle, + PCHAR Section, + PCHAR Key, + PINFCONTEXT Context) +{ + PINFCACHE Cache; + PINFCACHESECTION CacheSection; + PINFCACHELINE CacheLine; + + if (InfHandle == NULL || Section == NULL || Context == NULL) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + Cache = (PINFCACHE)InfHandle; + + /* Iterate through list of sections */ + CacheSection = Cache->FirstSection; + while (Section != NULL) + { +// DPRINT("Comparing '%S' and '%S'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (stricmp(CacheSection->Name, Section) == 0) + { + if (Key != NULL) + { + CacheLine = InfpCacheFindKeyLine (CacheSection, Key); + } + else + { + CacheLine = CacheSection->FirstLine; + } + + if (CacheLine == NULL) + return FALSE; + + Context->Inf = (PVOID)Cache; + Context->Section = (PVOID)CacheSection; + Context->Line = (PVOID)CacheLine; + + return TRUE; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + +// DPRINT("Section not found\n"); + + return FALSE; +} + + +BOOLEAN +InfFindNextLine (PINFCONTEXT ContextIn, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL) + return FALSE; + + if (ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + if (CacheLine->Next == NULL) + return FALSE; + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)(CacheLine->Next); + + return TRUE; +} + + +BOOLEAN +InfFindFirstMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL) + return FALSE; + + CacheLine = ((PINFCACHESECTION)(ContextIn->Section))->FirstLine; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && stricmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +BOOLEAN +InfFindNextMatchLine (PINFCONTEXT ContextIn, + PCHAR Key, + PINFCONTEXT ContextOut) +{ + PINFCACHELINE CacheLine; + + if (ContextIn == NULL || ContextOut == NULL || Key == NULL || *Key == 0) + return FALSE; + + if (ContextIn->Inf == NULL || ContextIn->Section == NULL || ContextIn->Line == NULL) + return FALSE; + + CacheLine = (PINFCACHELINE)ContextIn->Line; + while (CacheLine != NULL) + { + if (CacheLine->Key != NULL && stricmp (CacheLine->Key, Key) == 0) + { + + if (ContextIn != ContextOut) + { + ContextOut->Inf = ContextIn->Inf; + ContextOut->Section = ContextIn->Section; + } + ContextOut->Line = (PVOID)CacheLine; + + return TRUE; + } + + CacheLine = CacheLine->Next; + } + + return FALSE; +} + + +S32 +InfGetLineCount(HINF InfHandle, + PCHAR 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 (Section != NULL) + { +// DPRINT("Comparing '%S' and '%S'\n", CacheSection->Name, Section); + + /* Are the section names the same? */ + if (stricmp(CacheSection->Name, Section) == 0) + { + return CacheSection->LineCount; + } + + /* Get the next section */ + CacheSection = CacheSection->Next; + } + +// DPRINT("Section not found\n"); + + return -1; +} + + +/* InfGetLineText */ + + +S32 +InfGetFieldCount(PINFCONTEXT Context) +{ + if (Context == NULL || Context->Line == NULL) + return 0; + + return ((PINFCACHELINE)Context->Line)->FieldCount; +} + + +BOOLEAN +InfGetBinaryField (PINFCONTEXT Context, + U32 FieldIndex, + PU8 ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + U32 Index; + U32 Size; + PU8 Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + 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 FALSE; + + /* Copy binary data */ + Ptr = ReturnBuffer; + while (CacheField != NULL) + { + *Ptr = (UCHAR)atoi(CacheField->Data); //strtoul (CacheField->Data, NULL, 16); + + Ptr++; + CacheField = CacheField->Next; + } + } + + return TRUE; +} + + +BOOLEAN +InfGetIntField (PINFCONTEXT Context, + U32 FieldIndex, + S32 *IntegerValue) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + U32 Index; + PCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || IntegerValue == NULL) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + *IntegerValue = atoi (Ptr); //strtol (Ptr, NULL, 0); + + return TRUE; +} + + +BOOLEAN +InfGetMultiSzField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + PINFCACHEFIELD FieldPtr; + U32 Index; + U32 Size; + PCHAR Ptr; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + 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 += (strlen (FieldPtr->Data) + 1); + FieldPtr = FieldPtr->Next; + } + Size++; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + /* Copy multi-sz string */ + Ptr = ReturnBuffer; + FieldPtr = CacheField; + while (FieldPtr != NULL) + { + Size = strlen (FieldPtr->Data) + 1; + + strcpy (Ptr, FieldPtr->Data); + + Ptr = Ptr + Size; + FieldPtr = FieldPtr->Next; + } + *Ptr = 0; + } + + return TRUE; +} + + +BOOLEAN +InfGetStringField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR ReturnBuffer, + U32 ReturnBufferSize, + PU32 RequiredSize) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + U32 Index; + PCHAR Ptr; + U32 Size; + + if (Context == NULL || Context->Line == NULL || FieldIndex == 0) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + if (RequiredSize != NULL) + *RequiredSize = 0; + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + Ptr = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + Ptr = CacheField->Data; + } + + Size = strlen (Ptr) + 1; + + if (RequiredSize != NULL) + *RequiredSize = Size; + + if (ReturnBuffer != NULL) + { + if (ReturnBufferSize < Size) + return FALSE; + + strcpy (ReturnBuffer, Ptr); + } + + return TRUE; +} + + + + +BOOLEAN +InfGetData (PINFCONTEXT Context, + PCHAR *Key, + PCHAR *Data) +{ + PINFCACHELINE CacheKey; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + 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 TRUE; +} + + +BOOLEAN +InfGetDataField (PINFCONTEXT Context, + U32 FieldIndex, + PCHAR *Data) +{ + PINFCACHELINE CacheLine; + PINFCACHEFIELD CacheField; + U32 Index; + + if (Context == NULL || Context->Line == NULL || Data == NULL) + { +// DPRINT("Invalid parameter\n"); + return FALSE; + } + + CacheLine = (PINFCACHELINE)Context->Line; + + if (FieldIndex > CacheLine->FieldCount) + return FALSE; + + if (FieldIndex == 0) + { + *Data = CacheLine->Key; + } + else + { + CacheField = CacheLine->FirstField; + for (Index = 1; Index < FieldIndex; Index++) + CacheField = CacheField->Next; + + *Data = CacheField->Data; + } + + return TRUE; +} + + +/* EOF */ diff --git a/freeldr/freeldr/inifile/inifile.c b/freeldr/freeldr/inifile/inifile.c index 4b8d32796bf..4456df98834 100644 --- a/freeldr/freeldr/inifile/inifile.c +++ b/freeldr/freeldr/inifile/inifile.c @@ -30,6 +30,9 @@ BOOL IniOpenSection(PUCHAR SectionName, U32* SectionId) DbgPrint((DPRINT_INIFILE, "IniOpenSection() SectionName = %s\n", SectionName)); + if (!IniFileSectionListHead) + return FALSE; + // Loop through each section and find the one they want Section = (PINI_SECTION)RtlListGetHead((PLIST_ITEM)IniFileSectionListHead); while (Section != NULL) diff --git a/freeldr/freeldr/miscboot.c b/freeldr/freeldr/miscboot.c index 154b69f017c..6feee0572d5 100644 --- a/freeldr/freeldr/miscboot.c +++ b/freeldr/freeldr/miscboot.c @@ -17,7 +17,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - + #include #include #include diff --git a/freeldr/freeldr/multiboot.c b/freeldr/freeldr/multiboot.c index 4f6f6195d27..5db72524353 100644 --- a/freeldr/freeldr/multiboot.c +++ b/freeldr/freeldr/multiboot.c @@ -207,6 +207,7 @@ PVOID MultiBootLoadModule(FILE *ModuleImage, char *ModuleName, U32* ModuleSize) return((PVOID)pModule->mod_start); } +#if 0 int GetBootPartition(char *OperatingSystemName) { int BootPartitionNumber = -1; @@ -223,7 +224,7 @@ int GetBootPartition(char *OperatingSystemName) return BootPartitionNumber; } - +#endif PVOID MultiBootCreateModule(char *ModuleName) { diff --git a/freeldr/freeldr/reactos/reactos.c b/freeldr/freeldr/reactos/reactos.c index 0d50df4d9aa..ded0ef8521f 100644 --- a/freeldr/freeldr/reactos/reactos.c +++ b/freeldr/freeldr/reactos/reactos.c @@ -662,21 +662,8 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName) FilePointer = FsOpenFile(szFileName); if (FilePointer == NULL) { - strcpy(szFileName, szBootPath); - strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM.HIV"); - - DbgPrint((DPRINT_REACTOS, "SystemHive: '%s'", szFileName)); - - FilePointer = FsOpenFile(szFileName); - if (FilePointer == NULL) - { - UiMessageBox("Could not find the System hive!"); - return; - } - else - { - TextHive = TRUE; - } + UiMessageBox("Could not find the System hive!"); + return; } /* @@ -702,14 +689,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName) /* * Import the loaded system hive */ - if (TextHive) - { - RegImportTextHive(Base, Size); - } - else - { - RegImportBinaryHive(Base, Size); - } + RegImportBinaryHive(Base, Size); /* * Initialize the 'CurrentControlSet' link diff --git a/freeldr/freeldr/reactos/reghive.c b/freeldr/freeldr/reactos/reghive.c deleted file mode 100644 index 93000a31076..00000000000 --- a/freeldr/freeldr/reactos/reghive.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * FreeLoader - * - * Copyright (C) 2001 Rex Jolliff - * Copyright (C) 2001 Eric Kohl - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -#include "registry.h" - - -#define REGISTRY_FILE_MAGIC "REGEDIT4" - -static PCHAR -checkAndSkipMagic (PCHAR regChunk) -{ - if (strncmp (regChunk, - REGISTRY_FILE_MAGIC, - strlen (REGISTRY_FILE_MAGIC)) != 0) - { - DbgPrint((DPRINT_REGISTRY, "Incorrect magic number in registry chunk. Expected: '%s' Got: '%.*s'\n", - REGISTRY_FILE_MAGIC, strlen(REGISTRY_FILE_MAGIC), regChunk)); - - return 0; - } - regChunk += strlen (REGISTRY_FILE_MAGIC); - - DbgPrint((DPRINT_REGISTRY, "Found registry chunk magic value\n")); - - return regChunk; -} - -static PCHAR -skipWhitespaceInChunk (PCHAR regChunk) -{ - while (*regChunk && isspace (*regChunk)) - regChunk++; - - return *regChunk ? regChunk : 0; -} - -static int -computeKeyNameSize (PCHAR regChunk) -{ - int copyCount = 0; - - while (*regChunk != 0 && *regChunk != ']') - { - copyCount++; - regChunk++; - } - - return copyCount; -} - -static BOOL -allocateKeyName(PCHAR *newKeyName, int newKeySize) -{ - if (*newKeyName != NULL) - MmFreeMemory(*newKeyName); - - *newKeyName = MmAllocateMemory(newKeySize + 1); - if (*newKeyName == NULL) - return(FALSE); - - memset(*newKeyName, 0, newKeySize + 1); - - return(TRUE); -} - -static PCHAR -skipToNextKeyInChunk (PCHAR regChunk) -{ - while (*regChunk != 0 && *regChunk != '[') - { - while (*regChunk != 0 && *regChunk != '\n') - { - regChunk++; - } - regChunk++; - } - - return *regChunk ? regChunk : 0; -} - -static PCHAR -getKeyNameFromChunk (PCHAR regChunk, PCHAR newKeyName) -{ - int index = 0; - - while (*regChunk != 0 && *regChunk != ']') - { - newKeyName[index++] = *regChunk++; - } - newKeyName[index] = '\0'; - - return *regChunk ? regChunk : 0; -} - -static HKEY -createNewKey (PCHAR newKeyName) -{ - HKEY handleToReturn = NULL; - - DbgPrint((DPRINT_REGISTRY, "Adding new key '%s'\n", newKeyName)); - - RegCreateKey(NULL, - newKeyName, - &handleToReturn); - - DbgPrint((DPRINT_REGISTRY, "Returned handle: 0x%x\n", handleToReturn)); - - return handleToReturn; -} - -static PCHAR -skipToNextKeyValueInChunk (PCHAR regChunk) -{ - while (*regChunk != 0 && *regChunk != '\n') - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - - return regChunk; -} - -static int -computeKeyValueNameSize (PCHAR regChunk) -{ - int size = 0; - - if (*regChunk != '\"') - return 0; - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - size++; - regChunk++; - } - - return regChunk ? size : 0; -} - -static PCHAR -getKeyValueNameFromChunk (PCHAR regChunk, PCHAR newKeyName) -{ - int index = 0; - - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - newKeyName[index++] = *regChunk++; - } - newKeyName[index] = '\0'; - regChunk++; - - return *regChunk ? regChunk : 0; -} - -static PCHAR -getKeyValueTypeFromChunk (PCHAR regChunk, PCHAR dataFormat, int *keyValueType) -{ - if (*regChunk == '\"') - { - strcpy (dataFormat, "string"); - *keyValueType = REG_SZ; - } - else if (strncmp (regChunk, "hex", 3) == 0) - { - strcpy (dataFormat, "hex"); - regChunk += 3; - if (*regChunk == '(') - { - regChunk++; - *keyValueType = atoi (regChunk); - while (*regChunk != 0 && *regChunk != ')') - regChunk++; - regChunk++; - } - else - *keyValueType = REG_BINARY; - if (*regChunk == ':') - regChunk++; - } - else if (strncmp (regChunk, "dword", 5) == 0) - { - strcpy (dataFormat, "dword"); - *keyValueType = REG_DWORD; - regChunk += 5; - if (*regChunk == ':') - regChunk++; - } - else if (strncmp (regChunk, "multi", 5) == 0) - { - strcpy (dataFormat, "multi"); - *keyValueType = REG_MULTI_SZ; - regChunk += 5; - if (*regChunk == ':') - regChunk++; - } - else if (strncmp (regChunk, "expand", 6) == 0) - { - strcpy (dataFormat, "expand"); - *keyValueType = REG_EXPAND_SZ; - regChunk += 6; - if (*regChunk == ':') - regChunk++; - } - else - { - UNIMPLEMENTED(); - } - - return *regChunk ? regChunk : 0; -} - -static int -computeKeyValueDataSize (PCHAR regChunk, PCHAR dataFormat) -{ - int dataSize = 0; - - if (strcmp (dataFormat, "string") == 0) - { - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - dataSize++; - regChunk++; - } - dataSize++; - } - else if (strcmp (dataFormat, "hex") == 0) - { - while (*regChunk != 0 && isxdigit(*regChunk)) - { - regChunk++; - regChunk++; - dataSize++; - if (*regChunk == ',') - { - regChunk++; - if (*regChunk == '\\') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - } - } - } - } - else if (strcmp (dataFormat, "dword") == 0) - { - dataSize = sizeof(U32); - while (*regChunk != 0 && isxdigit(*regChunk)) - { - regChunk++; - } - } - else if (strcmp (dataFormat, "multi") == 0) - { - while (*regChunk == '\"') - { - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - dataSize++; - regChunk++; - } - regChunk++; - dataSize++; - if (*regChunk == ',') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - if (*regChunk == '\\') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - } - } - else - break; - } - dataSize++; - } - else if (strcmp (dataFormat, "expand") == 0) - { - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - dataSize++; - regChunk++; - } - dataSize++; - } - else - { - UNIMPLEMENTED(); - } - - return dataSize; -} - -static BOOL -allocateDataBuffer (PVOID * data, int * dataBufferSize, int dataSize) -{ - if (*dataBufferSize < dataSize) - { - if (*dataBufferSize > 0) - MmFreeMemory(*data); - *data = MmAllocateMemory(dataSize); - *dataBufferSize = dataSize; - } - - return TRUE; -} - -static PCHAR -getKeyValueDataFromChunk (PCHAR regChunk, PCHAR dataFormat, PCHAR data) -{ - char dataValue; - U32 ulValue; - PCHAR ptr; - - if (strcmp (dataFormat, "string") == 0) - { - /* convert quoted string to zero-terminated Unicode string */ - ptr = (PCHAR)data; - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - *ptr++ = (CHAR)*regChunk++; - } - *ptr = 0; - regChunk++; - } - else if (strcmp (dataFormat, "hex") == 0) - { - while (*regChunk != 0 && isxdigit (*regChunk)) - { - dataValue = (isdigit (*regChunk) ? *regChunk - '0' : - tolower(*regChunk) - 'a') << 4; - regChunk++; - dataValue += (isdigit (*regChunk) ? *regChunk - '0' : - tolower(*regChunk) - 'a'); - regChunk++; - *data++ = dataValue; - if (*regChunk == ',') - { - regChunk++; - if (*regChunk == '\\') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - } - } - } - } - else if (strcmp (dataFormat, "dword") == 0) - { - ulValue = 0; - while (*regChunk != 0 && isxdigit(*regChunk)) - { - dataValue = (isdigit (*regChunk) ? *regChunk - '0' : - tolower(*regChunk) - 'a'); - ulValue = (ulValue << 4) + dataValue; - regChunk++; - } - memcpy(data, &ulValue, sizeof(U32)); - } - else if (strcmp (dataFormat, "multi") == 0) - { - ptr = (PCHAR)data; - while (*regChunk == '\"') - { - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - *ptr++ = (CHAR)*regChunk++; - } - regChunk++; - *ptr++ = 0; - if (*regChunk == ',') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - if (*regChunk == '\\') - { - regChunk++; - regChunk = skipWhitespaceInChunk (regChunk); - } - } - else - break; - } - *ptr = 0; - } - else if (strcmp (dataFormat, "expand") == 0) - { - /* convert quoted string to zero-terminated Unicode string */ - ptr = (PCHAR)data; - regChunk++; - while (*regChunk != 0 && *regChunk != '\"') - { - *ptr++ = (CHAR)*regChunk++; - } - *ptr = 0; - regChunk++; - } - else - { - UNIMPLEMENTED(); - } - - return *regChunk ? regChunk : 0; -} - -static BOOL -setKeyValue (HKEY currentKey, - PCHAR newValueName, - U32 keyValueType, - PVOID data, - U32 dataSize) -{ - S32 status; - - DbgPrint((DPRINT_REGISTRY, "Adding value (%s) to current key, with data type %d and size %d\n", - newValueName, (int)keyValueType, (int)dataSize)); - - status = RegSetValue(currentKey, - newValueName, - keyValueType, - data, - dataSize); - if (status != ERROR_SUCCESS) - { - DbgPrint((DPRINT_REGISTRY, "Could not set key value. status: %d\n", status)); - return FALSE; - } - - return TRUE; -} - -BOOL -RegImportTextHive(PCHAR ChunkBase, - U32 ChunkSize) -{ - HKEY currentKey = INVALID_HANDLE_VALUE; - char *newKeyName = NULL; - int newKeySize; - char dataFormat [10]; - int keyValueType; - int dataSize = 0; - int dataBufferSize = 0; - PVOID data = 0; - PCHAR regChunk; - - DbgPrint((DPRINT_REGISTRY, "ChunkBase %p ChunkSize %lx\n", ChunkBase, ChunkSize)); - - regChunk = checkAndSkipMagic (ChunkBase); - if (regChunk == 0) - return FALSE; - - while (regChunk != 0 && *regChunk != 0 && (((U32)regChunk-(U32)ChunkBase) < ChunkSize)) - { - regChunk = skipWhitespaceInChunk (regChunk); - if (regChunk == 0) - continue; - - if (*regChunk == '[') - { - if (currentKey != INVALID_HANDLE_VALUE) - { - DbgPrint((DPRINT_REGISTRY, "Closing current key: 0x%lx\n", currentKey)); - currentKey = INVALID_HANDLE_VALUE; - } - - regChunk++; - - newKeySize = computeKeyNameSize (regChunk); - if (!allocateKeyName (&newKeyName, newKeySize)) - { - regChunk = 0; - continue; - } - - regChunk = getKeyNameFromChunk (regChunk, newKeyName); - if (regChunk == 0) - continue; - - currentKey = createNewKey (newKeyName); - if (currentKey == INVALID_HANDLE_VALUE) - { - regChunk = skipToNextKeyInChunk (regChunk); - continue; - } - - regChunk++; - } - else - { - if (currentKey == INVALID_HANDLE_VALUE) - { - regChunk = skipToNextKeyInChunk (regChunk); - continue; - } - - newKeySize = computeKeyValueNameSize (regChunk); - if (!allocateKeyName (&newKeyName, newKeySize)) - { - regChunk = 0; - continue; - } - - regChunk = getKeyValueNameFromChunk (regChunk, newKeyName); - if (regChunk == 0) - continue; - - if (*regChunk != '=') - { - regChunk = skipToNextKeyValueInChunk (regChunk); - continue; - } - regChunk++; - - regChunk = getKeyValueTypeFromChunk (regChunk, dataFormat, &keyValueType); - if (regChunk == 0) - continue; - - dataSize = computeKeyValueDataSize (regChunk, dataFormat); - if (!allocateDataBuffer (&data, &dataBufferSize, dataSize)) - { - regChunk = 0; - continue; - } - - regChunk = getKeyValueDataFromChunk (regChunk, dataFormat, data); - if (regChunk == 0) - continue; - - if (!setKeyValue (currentKey, newKeyName, keyValueType, data, dataSize)) - { - regChunk = 0; - continue; - } - } - } - - if (currentKey != INVALID_HANDLE_VALUE) - { - DbgPrint((DPRINT_REGISTRY, "Closing current key: 0x%lx\n", currentKey)); - } - - if (newKeyName != NULL) - { - MmFreeMemory(newKeyName); - } - - if (data != NULL) - { - MmFreeMemory(data); - } - - return TRUE; -} - -#if 0 -BOOL -RegExportHive(PCHAR ChunkBase, U32* ChunkSize) -{ - return(TRUE); -} -#endif - -/* EOF */ diff --git a/freeldr/freeldr/reactos/registry.h b/freeldr/freeldr/reactos/registry.h index 3b2ebadbbe5..4cfdb0fdc4a 100644 --- a/freeldr/freeldr/reactos/registry.h +++ b/freeldr/freeldr/reactos/registry.h @@ -288,10 +288,6 @@ U32 RegGetValueCount (HKEY Key); -BOOL -RegImportTextHive (PCHAR ChunkBase, - U32 ChunkSize); - BOOL RegImportBinaryHive (PCHAR ChunkBase, U32 ChunkSize); diff --git a/freeldr/freeldr/reactos/setupldr.c b/freeldr/freeldr/reactos/setupldr.c index ac63fe3c127..df8b15bcade 100644 --- a/freeldr/freeldr/reactos/setupldr.c +++ b/freeldr/freeldr/reactos/setupldr.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "registry.h" @@ -238,6 +239,10 @@ VOID RunLoader(VOID) char *SourcePath; char *LoadOptions; + HINF InfHandle; + U32 ErrorLine; + INFCONTEXT InfContext; + /* Setup multiboot information structure */ mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES; mb_info.mem_lower = GetConventionalMemorySize(); @@ -298,9 +303,46 @@ VOID RunLoader(VOID) ((char *)(&mb_info.boot_device))[1] = (char)BootPartition; - /* Set load options */ -// LoadOptions = "/DEBUGPORT=COM1"; - LoadOptions = "/DEBUGPORT=SCREEN"; + /* Open boot drive */ + if (!FsOpenVolume(BootDrive, BootPartition)) + { +#ifdef USE_UI + UiMessageBox("Failed to open boot drive."); +#else + printf("Failed to open boot drive."); +#endif + return; + } + + /* Open 'txtsetup.sif' */ + if (!InfOpenFile (&InfHandle, + (BootDrive < 0x80) ? "\\txtsetup.sif" : "\\reactos\\txtsetup.sif", + &ErrorLine)) + { + printf("Failed to open 'txtsetup.sif'\n"); + return; + } + + /* Get load options */ + if (!InfFindFirstLine (InfHandle, + "SetupData", + "OsLoadOptions", + &InfContext)) + { + printf("Failed to find 'SetupData/OsLoadOptions'\n"); + return; + } + + if (!InfGetDataField (&InfContext, + 1, + &LoadOptions)) + { + printf("Failed to get load options\n"); + return; + } +#if 0 + printf("LoadOptions: '%s'\n", LoadOptions); +#endif if (BootDrive < 0x80) { @@ -321,18 +363,6 @@ VOID RunLoader(VOID) SourcePath, LoadOptions); - - /* Open boot drive */ - if (!FsOpenVolume(BootDrive, BootPartition)) - { -#ifdef USE_UI - UiMessageBox("Failed to open boot drive."); -#else - printf("Failed to open boot drive."); -#endif - return; - } - /* Load ntoskrnl.exe */ if (!LoadKernel(SourcePath, "ntoskrnl.exe")) return;