mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:43:04 +00:00
Add hive maker. It does not export binary hives yet.
svn path=/trunk/; revision=4538
This commit is contained in:
parent
be94ceb3d5
commit
1a884ce84d
12 changed files with 3370 additions and 3 deletions
|
@ -14,7 +14,7 @@ TOOLS = \
|
||||||
|
|
||||||
CLEAN_FILES = $(TOOLS)
|
CLEAN_FILES = $(TOOLS)
|
||||||
|
|
||||||
all: $(TOOLS) wmc_directory_target cdmake_directory_target
|
all: $(TOOLS) wmc_target cdmake_target mkhive_target
|
||||||
|
|
||||||
buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h
|
buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h
|
||||||
$(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c
|
$(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c
|
||||||
|
@ -90,15 +90,20 @@ mkflpimg$(EXE_POSTFIX): mkflpimg.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
wmc_directory_target:
|
wmc_target:
|
||||||
$(MAKE) -C wmc wmc$(EXE_POSTFIX)
|
$(MAKE) -C wmc wmc$(EXE_POSTFIX)
|
||||||
|
|
||||||
cdmake_directory_target:
|
cdmake_target:
|
||||||
$(MAKE) -C cdmake cdmake$(EXE_POSTFIX)
|
$(MAKE) -C cdmake cdmake$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
mkhive_target:
|
||||||
|
$(MAKE) -C mkhive mkhive$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(HOST),mingw32-linux)
|
ifeq ($(HOST),mingw32-linux)
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C cdmake clean
|
$(MAKE) -C cdmake clean
|
||||||
|
$(MAKE) -C mkhive clean
|
||||||
$(MAKE) -C wmc clean
|
$(MAKE) -C wmc clean
|
||||||
rm mkconfig
|
rm mkconfig
|
||||||
rm $(TOOLS)
|
rm $(TOOLS)
|
||||||
|
@ -106,6 +111,7 @@ endif
|
||||||
ifeq ($(HOST),mingw32-windows)
|
ifeq ($(HOST),mingw32-windows)
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C cdmake clean
|
$(MAKE) -C cdmake clean
|
||||||
|
$(MAKE) -C mkhive clean
|
||||||
$(MAKE) -C wmc clean
|
$(MAKE) -C wmc clean
|
||||||
del *$(EXE_POSTFIX)
|
del *$(EXE_POSTFIX)
|
||||||
endif
|
endif
|
||||||
|
|
49
reactos/tools/mkhive/Makefile
Normal file
49
reactos/tools/mkhive/Makefile
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#
|
||||||
|
# Hive-Maker
|
||||||
|
#
|
||||||
|
PATH_TO_TOP = ../..
|
||||||
|
|
||||||
|
TARGET = mkhive$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
OBJECTS = mkhive.o binhive.o infcache.o reginf.o registry.o
|
||||||
|
|
||||||
|
CLEAN_FILES = *.o mkhive$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
HOST_CFLAGS = -I.
|
||||||
|
|
||||||
|
mkhive.o: mkhive.c
|
||||||
|
$(HOST_CC) $(HOST_CFLAGS) -c mkhive.c -o mkhive.o
|
||||||
|
|
||||||
|
binhive.o: binhive.c
|
||||||
|
$(HOST_CC) $(HOST_CFLAGS) -c binhive.c -o binhive.o
|
||||||
|
|
||||||
|
infcache.o: infcache.c
|
||||||
|
$(HOST_CC) $(HOST_CFLAGS) -c infcache.c -o infcache.o
|
||||||
|
|
||||||
|
reginf.o: reginf.c
|
||||||
|
$(HOST_CC) $(HOST_CFLAGS) -c reginf.c -o reginf.o
|
||||||
|
|
||||||
|
registry.o: registry.c
|
||||||
|
$(HOST_CC) $(HOST_CFLAGS) -c registry.c -o registry.o
|
||||||
|
|
||||||
|
mkhive$(EXE_POSTFIX): $(OBJECTS)
|
||||||
|
$(HOST_CC) $(OBJECTS) -o mkhive$(EXE_POSTFIX)
|
||||||
|
|
||||||
|
ifeq ($(HOST),mingw32-linux)
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f mkhive$(EXE_POSTFIX)
|
||||||
|
endif
|
||||||
|
ifeq ($(HOST),mingw32-windows)
|
||||||
|
clean:
|
||||||
|
del *.o
|
||||||
|
del mkhive$(EXE_POSTFIX)
|
||||||
|
endif
|
||||||
|
|
||||||
|
.phony: clean
|
||||||
|
|
||||||
|
include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
|
# EOF
|
38
reactos/tools/mkhive/binhive.c
Normal file
38
reactos/tools/mkhive/binhive.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: binhive.c,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/binhive.c
|
||||||
|
* PURPOSE: Binary hive export code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include "mkhive.h"
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ExportBinaryHive (PCHAR FileName,
|
||||||
|
PCHAR KeyName)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
36
reactos/tools/mkhive/binhive.h
Normal file
36
reactos/tools/mkhive/binhive.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: binhive.h,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/binhive.h
|
||||||
|
* PURPOSE: Binary hive export code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BINHIVE_H__
|
||||||
|
#define __BINHIVE_H__
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ExportBinaryHive (PCHAR FileName,
|
||||||
|
PCHAR KeyName);
|
||||||
|
|
||||||
|
#endif /* __BINHIVE_H__ */
|
||||||
|
|
||||||
|
/* EOF */
|
1478
reactos/tools/mkhive/infcache.c
Normal file
1478
reactos/tools/mkhive/infcache.c
Normal file
File diff suppressed because it is too large
Load diff
132
reactos/tools/mkhive/infcache.h
Normal file
132
reactos/tools/mkhive/infcache.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: infcache.h,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/infcache.h
|
||||||
|
* PURPOSE: INF file parser that caches contents of INF file in memory
|
||||||
|
* PROGRAMMER: Royce Mitchell III
|
||||||
|
* Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#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 PVOID HINF, *PHINF;
|
||||||
|
|
||||||
|
typedef struct _INFCONTEXT
|
||||||
|
{
|
||||||
|
PVOID Inf;
|
||||||
|
// PVOID CurrentInf;
|
||||||
|
PVOID Section;
|
||||||
|
PVOID Line;
|
||||||
|
} INFCONTEXT, *PINFCONTEXT;
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfOpenFile (PHINF InfHandle,
|
||||||
|
PCHAR FileName,
|
||||||
|
PULONG ErrorLine);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
InfCloseFile (HINF InfHandle);
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfFindFirstLine (HINF InfHandle,
|
||||||
|
PCHAR Section,
|
||||||
|
PCHAR Key,
|
||||||
|
PINFCONTEXT Context);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfFindNextLine (PINFCONTEXT ContextIn,
|
||||||
|
PINFCONTEXT ContextOut);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfFindFirstMatchLine (PINFCONTEXT ContextIn,
|
||||||
|
PCHAR Key,
|
||||||
|
PINFCONTEXT ContextOut);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfFindNextMatchLine (PINFCONTEXT ContextIn,
|
||||||
|
PCHAR Key,
|
||||||
|
PINFCONTEXT ContextOut);
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
InfGetLineCount (HINF InfHandle,
|
||||||
|
PCHAR Section);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
InfGetFieldCount (PINFCONTEXT Context);
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetBinaryField (PINFCONTEXT Context,
|
||||||
|
ULONG FieldIndex,
|
||||||
|
PUCHAR ReturnBuffer,
|
||||||
|
ULONG ReturnBufferSize,
|
||||||
|
PULONG RequiredSize);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetIntField (PINFCONTEXT Context,
|
||||||
|
ULONG FieldIndex,
|
||||||
|
PLONG IntegerValue);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetMultiSzField (PINFCONTEXT Context,
|
||||||
|
ULONG FieldIndex,
|
||||||
|
PCHAR ReturnBuffer,
|
||||||
|
ULONG ReturnBufferSize,
|
||||||
|
PULONG RequiredSize);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetStringField (PINFCONTEXT Context,
|
||||||
|
ULONG FieldIndex,
|
||||||
|
PCHAR ReturnBuffer,
|
||||||
|
ULONG ReturnBufferSize,
|
||||||
|
PULONG RequiredSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetData (PINFCONTEXT Context,
|
||||||
|
PCHAR *Key,
|
||||||
|
PCHAR *Data);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
InfGetDataField (PINFCONTEXT Context,
|
||||||
|
ULONG FieldIndex,
|
||||||
|
PCHAR *Data);
|
||||||
|
|
||||||
|
#endif /* __INFCACHE_H__ */
|
||||||
|
|
||||||
|
/* EOF */
|
97
reactos/tools/mkhive/mkhive.c
Normal file
97
reactos/tools/mkhive/mkhive.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: mkhive.c,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/mkhive.c
|
||||||
|
* PURPOSE: Hive maker
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mkhive.h"
|
||||||
|
#include "registry.h"
|
||||||
|
#include "reginf.h"
|
||||||
|
#include "binhive.h"
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 260
|
||||||
|
#endif
|
||||||
|
#define DIR_SEPARATOR_CHAR '/'
|
||||||
|
#define DIR_SEPARATOR_STRING "/"
|
||||||
|
#else
|
||||||
|
#define DIR_SEPARATOR_CHAR '\\'
|
||||||
|
#define DIR_SEPARATOR_STRING "\\"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void usage (void)
|
||||||
|
{
|
||||||
|
printf ("Usage: mkhive <srcdir> <dstdir>\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char FileName[PATH_MAX];
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
usage ();
|
||||||
|
}
|
||||||
|
|
||||||
|
RegInitializeRegistry ();
|
||||||
|
|
||||||
|
strcpy (FileName, argv[1]);
|
||||||
|
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||||
|
strcat (FileName, "hivesys.inf");
|
||||||
|
ImportRegistryFile (FileName, "AddReg", FALSE);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
strcpy (FileName, argv[1]);
|
||||||
|
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||||
|
strcat (FileName, "hivecls.inf");
|
||||||
|
ImportRegistryFile (FileName, "AddReg", FALSE);
|
||||||
|
|
||||||
|
strcpy (FileName, argv[1]);
|
||||||
|
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||||
|
strcat (FileName, "hivesft.inf");
|
||||||
|
ImportRegistryFile (FileName, "AddReg", FALSE);
|
||||||
|
|
||||||
|
strcpy (FileName, argv[1]);
|
||||||
|
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||||
|
strcat (FileName, "hivedef.inf");
|
||||||
|
ImportRegistryFile (FileName, "AddReg", FALSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcpy (FileName, argv[2]);
|
||||||
|
strcat (FileName, DIR_SEPARATOR_STRING);
|
||||||
|
strcat (FileName, "system");
|
||||||
|
ExportBinaryHive (FileName, "\\Registy\\Machine\\System");
|
||||||
|
|
||||||
|
|
||||||
|
// RegShutdownRegistry ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
74
reactos/tools/mkhive/mkhive.h
Normal file
74
reactos/tools/mkhive/mkhive.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: mkhive.h,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/mkhive.h
|
||||||
|
* PURPOSE: Hive maker
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MKHIVE_H__
|
||||||
|
#define __MKHIVE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#define VOID void
|
||||||
|
typedef void *PVOID;
|
||||||
|
typedef char CHAR, *PCHAR;
|
||||||
|
typedef unsigned char UCHAR, *PUCHAR;
|
||||||
|
typedef short SHORT, *PSHORT;
|
||||||
|
typedef unsigned short USHORT, *PUSHORT;
|
||||||
|
typedef long LONG, *PLONG;
|
||||||
|
typedef unsigned long ULONG, *PULONG;
|
||||||
|
|
||||||
|
typedef int BOOL, *PBOOL;
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void*)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Debugging macros */
|
||||||
|
|
||||||
|
#define DPRINT1(args...) do { printf("(%s:%d) ",__FILE__,__LINE__); printf(args); } while(0);
|
||||||
|
#define CHECKPOINT1 do { printf("%s:%d\n",__FILE__,__LINE__); } while(0);
|
||||||
|
|
||||||
|
#define DPRINT(args...)
|
||||||
|
#define CHECKPOINT
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __MKHIVE_H__ */
|
||||||
|
|
||||||
|
/* EOF */
|
470
reactos/tools/mkhive/reginf.c
Normal file
470
reactos/tools/mkhive/reginf.c
Normal file
|
@ -0,0 +1,470 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: reginf.c,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/reginf.h
|
||||||
|
* PURPOSE: Inf file import code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mkhive.h"
|
||||||
|
#include "registry.h"
|
||||||
|
#include "infcache.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define FLG_ADDREG_BINVALUETYPE 0x00000001
|
||||||
|
#define FLG_ADDREG_NOCLOBBER 0x00000002
|
||||||
|
#define FLG_ADDREG_DELVAL 0x00000004
|
||||||
|
#define FLG_ADDREG_APPEND 0x00000008
|
||||||
|
#define FLG_ADDREG_KEYONLY 0x00000010
|
||||||
|
#define FLG_ADDREG_OVERWRITEONLY 0x00000020
|
||||||
|
#define FLG_ADDREG_TYPE_SZ 0x00000000
|
||||||
|
#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
|
||||||
|
#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
|
||||||
|
#define FLG_ADDREG_TYPE_BINARY (0x00000000 | FLG_ADDREG_BINVALUETYPE)
|
||||||
|
#define FLG_ADDREG_TYPE_DWORD (0x00010000 | FLG_ADDREG_BINVALUETYPE)
|
||||||
|
#define FLG_ADDREG_TYPE_NONE (0x00020000 | FLG_ADDREG_BINVALUETYPE)
|
||||||
|
#define FLG_ADDREG_TYPE_MASK (0xFFFF0000 | FLG_ADDREG_BINVALUETYPE)
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
GetRootKey (PCHAR Name)
|
||||||
|
{
|
||||||
|
if (!stricmp (Name, "HKCR"))
|
||||||
|
{
|
||||||
|
strcpy (Name, "\\Registry\\Machine\\SOFTWARE\\Classes\\");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stricmp (Name, "HKCU"))
|
||||||
|
{
|
||||||
|
strcpy (Name, "\\Registry\\User\\.DEFAULT\\");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stricmp (Name, "HKLM"))
|
||||||
|
{
|
||||||
|
strcpy (Name, "\\Registry\\Machine\\");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stricmp (Name, "HKU"))
|
||||||
|
{
|
||||||
|
strcpy (Name, "\\Registry\\User\\");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!stricmp (Name, "HKR"))
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* append_multi_sz_value
|
||||||
|
*
|
||||||
|
* Append a multisz string to a multisz registry value.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
static void
|
||||||
|
append_multi_sz_value (HANDLE hkey,
|
||||||
|
const WCHAR *value,
|
||||||
|
const WCHAR *strings,
|
||||||
|
DWORD str_size )
|
||||||
|
{
|
||||||
|
DWORD size, type, total;
|
||||||
|
WCHAR *buffer, *p;
|
||||||
|
|
||||||
|
if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
|
||||||
|
if (type != REG_MULTI_SZ) return;
|
||||||
|
|
||||||
|
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (size + str_size) * sizeof(WCHAR) ))) return;
|
||||||
|
if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
|
||||||
|
|
||||||
|
/* compare each string against all the existing ones */
|
||||||
|
total = size;
|
||||||
|
while (*strings)
|
||||||
|
{
|
||||||
|
int len = strlenW(strings) + 1;
|
||||||
|
|
||||||
|
for (p = buffer; *p; p += strlenW(p) + 1)
|
||||||
|
if (!strcmpiW( p, strings )) break;
|
||||||
|
|
||||||
|
if (!*p) /* not found, need to append it */
|
||||||
|
{
|
||||||
|
memcpy( p, strings, len * sizeof(WCHAR) );
|
||||||
|
p[len] = 0;
|
||||||
|
total += len;
|
||||||
|
}
|
||||||
|
strings += len;
|
||||||
|
}
|
||||||
|
if (total != size)
|
||||||
|
{
|
||||||
|
TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer) );
|
||||||
|
RegSetValueExW( hkey, value, 0, REG_MULTI_SZ, (BYTE *)buffer, total );
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
HeapFree( GetProcessHeap(), 0, buffer );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* delete_multi_sz_value
|
||||||
|
*
|
||||||
|
* Remove a string from a multisz registry value.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
static void delete_multi_sz_value( HKEY hkey, const WCHAR *value, const WCHAR *string )
|
||||||
|
{
|
||||||
|
DWORD size, type;
|
||||||
|
WCHAR *buffer, *src, *dst;
|
||||||
|
|
||||||
|
if (RegQueryValueExW( hkey, value, NULL, &type, NULL, &size )) return;
|
||||||
|
if (type != REG_MULTI_SZ) return;
|
||||||
|
/* allocate double the size, one for value before and one for after */
|
||||||
|
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size * 2 * sizeof(WCHAR) ))) return;
|
||||||
|
if (RegQueryValueExW( hkey, value, NULL, NULL, (BYTE *)buffer, &size )) goto done;
|
||||||
|
src = buffer;
|
||||||
|
dst = buffer + size;
|
||||||
|
while (*src)
|
||||||
|
{
|
||||||
|
int len = strlenW(src) + 1;
|
||||||
|
if (strcmpiW( src, string ))
|
||||||
|
{
|
||||||
|
memcpy( dst, src, len * sizeof(WCHAR) );
|
||||||
|
dst += len;
|
||||||
|
}
|
||||||
|
src += len;
|
||||||
|
}
|
||||||
|
*dst++ = 0;
|
||||||
|
if (dst != buffer + 2*size) /* did we remove something? */
|
||||||
|
{
|
||||||
|
TRACE( "setting value %s to %s\n", debugstr_w(value), debugstr_w(buffer + size) );
|
||||||
|
RegSetValueExW( hkey, value, 0, REG_MULTI_SZ,
|
||||||
|
(BYTE *)(buffer + size), dst - (buffer + size) );
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
HeapFree( GetProcessHeap(), 0, buffer );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* do_reg_operation
|
||||||
|
*
|
||||||
|
* Perform an add/delete registry operation depending on the flags.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
do_reg_operation(HKEY KeyHandle,
|
||||||
|
PCHAR ValueName,
|
||||||
|
PINFCONTEXT Context,
|
||||||
|
ULONG Flags)
|
||||||
|
{
|
||||||
|
CHAR EmptyStr = (CHAR)0;
|
||||||
|
ULONG Type;
|
||||||
|
ULONG Size;
|
||||||
|
// NTSTATUS Status;
|
||||||
|
|
||||||
|
if (Flags & FLG_ADDREG_DELVAL) /* deletion */
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (ValueName)
|
||||||
|
{
|
||||||
|
RegDeleteValueW( hkey, value );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegDeleteKeyW( hkey, NULL );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Flags & FLG_ADDREG_KEYONLY)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (Flags & (FLG_ADDREG_NOCLOBBER | FLG_ADDREG_OVERWRITEONLY))
|
||||||
|
{
|
||||||
|
BOOL exists = !RegQueryValueExW( hkey, value, NULL, NULL, NULL, NULL );
|
||||||
|
if (exists && (flags & FLG_ADDREG_NOCLOBBER))
|
||||||
|
return TRUE;
|
||||||
|
if (!exists & (flags & FLG_ADDREG_OVERWRITEONLY))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (Flags & FLG_ADDREG_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case FLG_ADDREG_TYPE_SZ:
|
||||||
|
Type = REG_SZ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLG_ADDREG_TYPE_MULTI_SZ:
|
||||||
|
Type = REG_MULTI_SZ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLG_ADDREG_TYPE_EXPAND_SZ:
|
||||||
|
Type = REG_EXPAND_SZ;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLG_ADDREG_TYPE_BINARY:
|
||||||
|
Type = REG_BINARY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLG_ADDREG_TYPE_DWORD:
|
||||||
|
Type = REG_DWORD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLG_ADDREG_TYPE_NONE:
|
||||||
|
Type = REG_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Type = Flags >> 16;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Flags & FLG_ADDREG_BINVALUETYPE) ||
|
||||||
|
(Type == REG_DWORD && InfGetFieldCount (Context) == 5))
|
||||||
|
{
|
||||||
|
PCHAR Str = NULL;
|
||||||
|
|
||||||
|
if (Type == REG_MULTI_SZ)
|
||||||
|
{
|
||||||
|
if (!InfGetMultiSzField (Context, 5, NULL, 0, &Size))
|
||||||
|
Size = 0;
|
||||||
|
|
||||||
|
if (Size)
|
||||||
|
{
|
||||||
|
Str = malloc (Size);
|
||||||
|
if (Str == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
InfGetMultiSzField (Context, 5, Str, Size, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Flags & FLG_ADDREG_APPEND)
|
||||||
|
{
|
||||||
|
if (Str == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// append_multi_sz_value( hkey, value, str, size );
|
||||||
|
|
||||||
|
free (Str);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/* else fall through to normal string handling */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!InfGetStringField (Context, 5, NULL, 0, &Size))
|
||||||
|
Size = 0;
|
||||||
|
|
||||||
|
if (Size)
|
||||||
|
{
|
||||||
|
Str = malloc (Size);
|
||||||
|
if (Str == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
InfGetStringField (Context, 5, Str, Size, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Type == REG_DWORD)
|
||||||
|
{
|
||||||
|
ULONG dw = Str ? strtol (Str, NULL, 0) : 0;
|
||||||
|
|
||||||
|
DPRINT("setting dword %s to %lx\n", ValueName, dw);
|
||||||
|
|
||||||
|
RegSetValue (KeyHandle,
|
||||||
|
ValueName,
|
||||||
|
Type,
|
||||||
|
(PVOID)&dw,
|
||||||
|
sizeof(ULONG));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT ("setting value %wZ to %S\n", ValueName, Str);
|
||||||
|
|
||||||
|
if (Str)
|
||||||
|
{
|
||||||
|
RegSetValue (KeyHandle,
|
||||||
|
ValueName,
|
||||||
|
Type,
|
||||||
|
(PVOID)Str,
|
||||||
|
Size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegSetValue (KeyHandle,
|
||||||
|
ValueName,
|
||||||
|
Type,
|
||||||
|
(PVOID)&EmptyStr,
|
||||||
|
sizeof(CHAR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free (Str);
|
||||||
|
}
|
||||||
|
else /* get the binary data */
|
||||||
|
{
|
||||||
|
PUCHAR Data = NULL;
|
||||||
|
|
||||||
|
if (!InfGetBinaryField (Context, 5, NULL, 0, &Size))
|
||||||
|
Size = 0;
|
||||||
|
|
||||||
|
if (Size)
|
||||||
|
{
|
||||||
|
Data = malloc (Size);
|
||||||
|
if (Data == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DPRINT("setting binary data %s len %lu\n", ValueName, Size);
|
||||||
|
InfGetBinaryField (Context, 5, Data, Size, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
RegSetValue (KeyHandle,
|
||||||
|
ValueName,
|
||||||
|
Type,
|
||||||
|
(PVOID)Data,
|
||||||
|
Size);
|
||||||
|
|
||||||
|
free (Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* registry_callback
|
||||||
|
*
|
||||||
|
* Called once for each AddReg and DelReg entry in a given section.
|
||||||
|
*/
|
||||||
|
static BOOL
|
||||||
|
registry_callback (HINF hInf, PCHAR Section, BOOL Delete)
|
||||||
|
{
|
||||||
|
CHAR Buffer[MAX_INF_STRING_LENGTH];
|
||||||
|
PCHAR ValuePtr;
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
INFCONTEXT Context;
|
||||||
|
HKEY KeyHandle;
|
||||||
|
BOOL Ok;
|
||||||
|
|
||||||
|
|
||||||
|
Ok = InfFindFirstLine (hInf, Section, NULL, &Context);
|
||||||
|
|
||||||
|
for (;Ok; Ok = InfFindNextLine (&Context, &Context))
|
||||||
|
{
|
||||||
|
/* get root */
|
||||||
|
if (!InfGetStringField (&Context, 1, Buffer, MAX_INF_STRING_LENGTH, NULL))
|
||||||
|
continue;
|
||||||
|
if (!GetRootKey (Buffer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* get key */
|
||||||
|
Length = strlen (Buffer);
|
||||||
|
if (!InfGetStringField (&Context, 2, Buffer + Length, MAX_INF_STRING_LENGTH - Length, NULL))
|
||||||
|
*Buffer = 0;
|
||||||
|
|
||||||
|
DPRINT("KeyName: <%s>\n", Buffer);
|
||||||
|
|
||||||
|
/* get flags */
|
||||||
|
if (!InfGetIntField (&Context, 4, (PLONG)&Flags))
|
||||||
|
Flags = 0;
|
||||||
|
|
||||||
|
DPRINT("Flags: %lx\n", Flags);
|
||||||
|
|
||||||
|
if (Delete || (Flags & FLG_ADDREG_OVERWRITEONLY))
|
||||||
|
{
|
||||||
|
if (RegOpenKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("RegOpenKey(%s) failed\n", Buffer);
|
||||||
|
continue; /* ignore if it doesn't exist */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (RegCreateKey (NULL, Buffer, &KeyHandle) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("RegCreateKey(%s) failed\n", Buffer);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get value name */
|
||||||
|
if (InfGetStringField (&Context, 3, Buffer, MAX_INF_STRING_LENGTH, NULL))
|
||||||
|
{
|
||||||
|
ValuePtr = Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ValuePtr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and now do it */
|
||||||
|
if (!do_reg_operation (KeyHandle, ValuePtr, &Context, Flags))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ImportRegistryFile(PCHAR FileName,
|
||||||
|
PCHAR Section,
|
||||||
|
BOOL Delete)
|
||||||
|
{
|
||||||
|
HINF hInf;
|
||||||
|
ULONG ErrorLine;
|
||||||
|
|
||||||
|
/* Load inf file from install media. */
|
||||||
|
if (!InfOpenFile(&hInf, FileName, &ErrorLine))
|
||||||
|
{
|
||||||
|
DPRINT1 ("InfOpenFile() failed\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!registry_callback (hInf, "AddReg", FALSE))
|
||||||
|
{
|
||||||
|
DPRINT1 ("registry_callback() failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
InfCloseFile (hInf);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
37
reactos/tools/mkhive/reginf.h
Normal file
37
reactos/tools/mkhive/reginf.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: reginf.h,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/reginf.h
|
||||||
|
* PURPOSE: Inf file import code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __REGINF_H__
|
||||||
|
#define __REGINF_H__
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
ImportRegistryFile(PCHAR Filename,
|
||||||
|
PCHAR Section,
|
||||||
|
BOOL Delete);
|
||||||
|
|
||||||
|
#endif /* __REGINF_H__ */
|
||||||
|
|
||||||
|
/* EOF */
|
653
reactos/tools/mkhive/registry.c
Normal file
653
reactos/tools/mkhive/registry.c
Normal file
|
@ -0,0 +1,653 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: registry.c,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/registry.c
|
||||||
|
* PURPOSE: Registry code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO:
|
||||||
|
* - Implement RegDeleteKey().
|
||||||
|
* - Implement RegQueryMultipleValue().
|
||||||
|
* - Fix RegEnumValue().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "mkhive.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
|
|
||||||
|
static HKEY RootKey;
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RegInitializeRegistry(VOID)
|
||||||
|
{
|
||||||
|
/* Create root key */
|
||||||
|
RootKey = (HKEY)malloc(sizeof(KEY));
|
||||||
|
|
||||||
|
InitializeListHead(&RootKey->SubKeyList);
|
||||||
|
InitializeListHead(&RootKey->ValueList);
|
||||||
|
InitializeListHead(&RootKey->KeyList);
|
||||||
|
|
||||||
|
RootKey->NameSize = 2;
|
||||||
|
RootKey->Name = (PUCHAR)malloc(2);
|
||||||
|
strcpy(RootKey->Name, "\\");
|
||||||
|
|
||||||
|
RootKey->DataType = 0;
|
||||||
|
RootKey->DataSize = 0;
|
||||||
|
RootKey->Data = NULL;
|
||||||
|
|
||||||
|
/* Create SYSTEM key */
|
||||||
|
RegCreateKey(RootKey,
|
||||||
|
"Registry\\Machine\\SYSTEM",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Create HARDWARE key */
|
||||||
|
RegCreateKey(RootKey,
|
||||||
|
"Registry\\Machine\\HARDWARE",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegCreateKey(HKEY ParentKey,
|
||||||
|
PCHAR KeyName,
|
||||||
|
PHKEY Key)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
HKEY SearchKey = INVALID_HANDLE_VALUE;
|
||||||
|
HKEY CurrentKey;
|
||||||
|
HKEY NewKey;
|
||||||
|
PCHAR p;
|
||||||
|
PCHAR name;
|
||||||
|
int subkeyLength;
|
||||||
|
int stringLength;
|
||||||
|
|
||||||
|
DPRINT ("KeyName '%s'\n", KeyName);
|
||||||
|
|
||||||
|
if (*KeyName == '\\')
|
||||||
|
{
|
||||||
|
KeyName++;
|
||||||
|
CurrentKey = RootKey;
|
||||||
|
}
|
||||||
|
else if (ParentKey == NULL)
|
||||||
|
{
|
||||||
|
CurrentKey = RootKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentKey = ParentKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether current key is a link */
|
||||||
|
if (CurrentKey->DataType == REG_LINK)
|
||||||
|
{
|
||||||
|
CurrentKey = (HKEY)CurrentKey->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*KeyName != 0)
|
||||||
|
{
|
||||||
|
DPRINT ("KeyName '%s'\n", KeyName);
|
||||||
|
|
||||||
|
if (*KeyName == '\\')
|
||||||
|
KeyName++;
|
||||||
|
p = strchr (KeyName, '\\');
|
||||||
|
if ((p != NULL) && (p != KeyName))
|
||||||
|
{
|
||||||
|
subkeyLength = p - KeyName;
|
||||||
|
stringLength = subkeyLength + 1;
|
||||||
|
name = KeyName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subkeyLength = strlen (KeyName);
|
||||||
|
stringLength = subkeyLength;
|
||||||
|
name = KeyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr = CurrentKey->SubKeyList.Flink;
|
||||||
|
while (Ptr != &CurrentKey->SubKeyList)
|
||||||
|
{
|
||||||
|
DPRINT ("Ptr 0x%x\n", Ptr);
|
||||||
|
|
||||||
|
SearchKey = CONTAINING_RECORD(Ptr,
|
||||||
|
KEY,
|
||||||
|
KeyList);
|
||||||
|
DPRINT ("SearchKey 0x%x\n", SearchKey);
|
||||||
|
DPRINT ("Searching '%s'\n", SearchKey->Name);
|
||||||
|
if (strncmp (SearchKey->Name, name, subkeyLength) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &CurrentKey->SubKeyList)
|
||||||
|
{
|
||||||
|
/* no key found -> create new subkey */
|
||||||
|
NewKey = (HKEY)malloc (sizeof(KEY));
|
||||||
|
if (NewKey == NULL)
|
||||||
|
return ERROR_OUTOFMEMORY;
|
||||||
|
|
||||||
|
InitializeListHead (&NewKey->SubKeyList);
|
||||||
|
InitializeListHead (&NewKey->ValueList);
|
||||||
|
|
||||||
|
NewKey->DataType = 0;
|
||||||
|
NewKey->DataSize = 0;
|
||||||
|
NewKey->Data = NULL;
|
||||||
|
|
||||||
|
InsertTailList (&CurrentKey->SubKeyList, &NewKey->KeyList);
|
||||||
|
NewKey->NameSize = subkeyLength + 1;
|
||||||
|
NewKey->Name = (PCHAR)malloc (NewKey->NameSize);
|
||||||
|
if (NewKey->Name == NULL)
|
||||||
|
return(ERROR_OUTOFMEMORY);
|
||||||
|
memcpy(NewKey->Name, name, subkeyLength);
|
||||||
|
NewKey->Name[subkeyLength] = 0;
|
||||||
|
|
||||||
|
DPRINT ("NewKey 0x%x\n", NewKey);
|
||||||
|
DPRINT ("NewKey '%s' Length %d\n", NewKey->Name, NewKey->NameSize);
|
||||||
|
|
||||||
|
CurrentKey = NewKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentKey = SearchKey;
|
||||||
|
|
||||||
|
/* Check whether current key is a link */
|
||||||
|
if (CurrentKey->DataType == REG_LINK)
|
||||||
|
{
|
||||||
|
CurrentKey = (HKEY)CurrentKey->Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyName = KeyName + stringLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key != NULL)
|
||||||
|
*Key = CurrentKey;
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegDeleteKey(HKEY Key,
|
||||||
|
PCHAR Name)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (strchr(Name, '\\') != NULL)
|
||||||
|
return(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegEnumKey(HKEY Key,
|
||||||
|
ULONG Index,
|
||||||
|
PCHAR Name,
|
||||||
|
PULONG NameSize)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
HKEY SearchKey;
|
||||||
|
ULONG Count = 0;
|
||||||
|
ULONG Size;
|
||||||
|
|
||||||
|
Ptr = Key->SubKeyList.Flink;
|
||||||
|
while (Ptr != &Key->SubKeyList)
|
||||||
|
{
|
||||||
|
if (Index == Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Count++;
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &Key->SubKeyList)
|
||||||
|
return(ERROR_NO_MORE_ITEMS);
|
||||||
|
|
||||||
|
SearchKey = CONTAINING_RECORD(Ptr,
|
||||||
|
KEY,
|
||||||
|
KeyList);
|
||||||
|
|
||||||
|
DPRINT ("Name '%s' Length %d\n", SearchKey->Name, SearchKey->NameSize);
|
||||||
|
|
||||||
|
Size = min(SearchKey->NameSize, *NameSize);
|
||||||
|
*NameSize = Size;
|
||||||
|
memcpy(Name, SearchKey->Name, Size);
|
||||||
|
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegOpenKey(HKEY ParentKey,
|
||||||
|
PCHAR KeyName,
|
||||||
|
PHKEY Key)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
HKEY SearchKey = INVALID_HANDLE_VALUE;
|
||||||
|
HKEY CurrentKey;
|
||||||
|
PCHAR p;
|
||||||
|
PCHAR name;
|
||||||
|
int subkeyLength;
|
||||||
|
int stringLength;
|
||||||
|
|
||||||
|
DPRINT("KeyName '%s'\n", KeyName);
|
||||||
|
|
||||||
|
*Key = NULL;
|
||||||
|
|
||||||
|
if (*KeyName == '\\')
|
||||||
|
{
|
||||||
|
KeyName++;
|
||||||
|
CurrentKey = RootKey;
|
||||||
|
}
|
||||||
|
else if (ParentKey == NULL)
|
||||||
|
{
|
||||||
|
CurrentKey = RootKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentKey = ParentKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether current key is a link */
|
||||||
|
if (CurrentKey->DataType == REG_LINK)
|
||||||
|
{
|
||||||
|
CurrentKey = (HKEY)CurrentKey->Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*KeyName != 0)
|
||||||
|
{
|
||||||
|
DPRINT ("KeyName '%s'\n", KeyName);
|
||||||
|
|
||||||
|
if (*KeyName == '\\')
|
||||||
|
KeyName++;
|
||||||
|
p = strchr(KeyName, '\\');
|
||||||
|
if ((p != NULL) && (p != KeyName))
|
||||||
|
{
|
||||||
|
subkeyLength = p - KeyName;
|
||||||
|
stringLength = subkeyLength + 1;
|
||||||
|
name = KeyName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subkeyLength = strlen(KeyName);
|
||||||
|
stringLength = subkeyLength;
|
||||||
|
name = KeyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr = CurrentKey->SubKeyList.Flink;
|
||||||
|
while (Ptr != &CurrentKey->SubKeyList)
|
||||||
|
{
|
||||||
|
DPRINT ("Ptr 0x%x\n", Ptr);
|
||||||
|
|
||||||
|
SearchKey = CONTAINING_RECORD(Ptr,
|
||||||
|
KEY,
|
||||||
|
KeyList);
|
||||||
|
|
||||||
|
DPRINT ("SearchKey 0x%x\n", SearchKey);
|
||||||
|
DPRINT ("Searching '%s'\n", SearchKey->Name);
|
||||||
|
|
||||||
|
if (strncmp(SearchKey->Name, name, subkeyLength) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &CurrentKey->SubKeyList)
|
||||||
|
{
|
||||||
|
return(ERROR_PATH_NOT_FOUND);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentKey = SearchKey;
|
||||||
|
|
||||||
|
/* Check whether current key is a link */
|
||||||
|
if (CurrentKey->DataType == REG_LINK)
|
||||||
|
{
|
||||||
|
CurrentKey = (HKEY)CurrentKey->Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyName = KeyName + stringLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Key != NULL)
|
||||||
|
*Key = CurrentKey;
|
||||||
|
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegSetValue(HKEY Key,
|
||||||
|
PCHAR ValueName,
|
||||||
|
ULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
ULONG DataSize)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
PVALUE Value = NULL;
|
||||||
|
|
||||||
|
DPRINT ("Key 0x%x, ValueName '%s', Type %d, Data 0x%x, DataSize %d\n",
|
||||||
|
(int)Key, ValueName, (int)Type, (int)Data, (int)DataSize);
|
||||||
|
|
||||||
|
if ((ValueName == NULL) || (*ValueName == 0))
|
||||||
|
{
|
||||||
|
/* set default value */
|
||||||
|
if ((Key->Data != NULL) && (Key->DataSize > sizeof(PUCHAR)))
|
||||||
|
{
|
||||||
|
free(Key->Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataSize <= sizeof(PUCHAR))
|
||||||
|
{
|
||||||
|
Key->DataSize = DataSize;
|
||||||
|
Key->DataType = Type;
|
||||||
|
memcpy(&Key->Data, Data, DataSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Key->Data = (PUCHAR)malloc(DataSize);
|
||||||
|
Key->DataSize = DataSize;
|
||||||
|
Key->DataType = Type;
|
||||||
|
memcpy(Key->Data, Data, DataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* set non-default value */
|
||||||
|
Ptr = Key->ValueList.Flink;
|
||||||
|
while (Ptr != &Key->ValueList)
|
||||||
|
{
|
||||||
|
Value = CONTAINING_RECORD(Ptr,
|
||||||
|
VALUE,
|
||||||
|
ValueList);
|
||||||
|
|
||||||
|
DPRINT ("Value->Name '%s'\n", Value->Name);
|
||||||
|
|
||||||
|
if (stricmp(Value->Name, ValueName) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &Key->ValueList)
|
||||||
|
{
|
||||||
|
/* add new value */
|
||||||
|
DPRINT("No value found - adding new value\n");
|
||||||
|
|
||||||
|
Value = (PVALUE)malloc(sizeof(VALUE));
|
||||||
|
if (Value == NULL)
|
||||||
|
return(ERROR_OUTOFMEMORY);
|
||||||
|
InsertTailList(&Key->ValueList, &Value->ValueList);
|
||||||
|
Value->NameSize = strlen(ValueName)+1;
|
||||||
|
Value->Name = (PCHAR)malloc(Value->NameSize);
|
||||||
|
if (Value->Name == NULL)
|
||||||
|
return(ERROR_OUTOFMEMORY);
|
||||||
|
strcpy(Value->Name, ValueName);
|
||||||
|
Value->DataType = REG_NONE;
|
||||||
|
Value->DataSize = 0;
|
||||||
|
Value->Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set new value */
|
||||||
|
if ((Value->Data != NULL) && (Value->DataSize > sizeof(PUCHAR)))
|
||||||
|
{
|
||||||
|
free(Value->Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DataSize <= sizeof(PUCHAR))
|
||||||
|
{
|
||||||
|
Value->DataSize = DataSize;
|
||||||
|
Value->DataType = Type;
|
||||||
|
memcpy(&Value->Data, Data, DataSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Value->Data = (PUCHAR)malloc(DataSize);
|
||||||
|
if (Value->Data == NULL)
|
||||||
|
return(ERROR_OUTOFMEMORY);
|
||||||
|
Value->DataType = Type;
|
||||||
|
Value->DataSize = DataSize;
|
||||||
|
memcpy(Value->Data, Data, DataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegQueryValue(HKEY Key,
|
||||||
|
PCHAR ValueName,
|
||||||
|
PULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
PULONG DataSize)
|
||||||
|
{
|
||||||
|
ULONG Size;
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
PVALUE Value = NULL;
|
||||||
|
|
||||||
|
if ((ValueName == NULL) || (*ValueName == 0))
|
||||||
|
{
|
||||||
|
/* query default value */
|
||||||
|
if (Key->Data == NULL)
|
||||||
|
return(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
if (Type != NULL)
|
||||||
|
*Type = Key->DataType;
|
||||||
|
if ((Data != NULL) && (DataSize != NULL))
|
||||||
|
{
|
||||||
|
if (Key->DataSize <= sizeof(PUCHAR))
|
||||||
|
{
|
||||||
|
Size = min(Key->DataSize, *DataSize);
|
||||||
|
memcpy(Data, &Key->Data, Size);
|
||||||
|
*DataSize = Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Size = min(Key->DataSize, *DataSize);
|
||||||
|
memcpy(Data, Key->Data, Size);
|
||||||
|
*DataSize = Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((Data == NULL) && (DataSize != NULL))
|
||||||
|
{
|
||||||
|
*DataSize = Key->DataSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* query non-default value */
|
||||||
|
Ptr = Key->ValueList.Flink;
|
||||||
|
while (Ptr != &Key->ValueList)
|
||||||
|
{
|
||||||
|
Value = CONTAINING_RECORD(Ptr,
|
||||||
|
VALUE,
|
||||||
|
ValueList);
|
||||||
|
|
||||||
|
DPRINT("Searching for '%s'. Value name '%s'\n", ValueName, Value->Name);
|
||||||
|
|
||||||
|
if (stricmp(Value->Name, ValueName) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &Key->ValueList)
|
||||||
|
return(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
if (Type != NULL)
|
||||||
|
*Type = Value->DataType;
|
||||||
|
if ((Data != NULL) && (DataSize != NULL))
|
||||||
|
{
|
||||||
|
if (Value->DataSize <= sizeof(PUCHAR))
|
||||||
|
{
|
||||||
|
Size = min(Value->DataSize, *DataSize);
|
||||||
|
memcpy(Data, &Value->Data, Size);
|
||||||
|
*DataSize = Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Size = min(Value->DataSize, *DataSize);
|
||||||
|
memcpy(Data, Value->Data, Size);
|
||||||
|
*DataSize = Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((Data == NULL) && (DataSize != NULL))
|
||||||
|
{
|
||||||
|
*DataSize = Value->DataSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegDeleteValue(HKEY Key,
|
||||||
|
PCHAR ValueName)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
PVALUE Value = NULL;
|
||||||
|
|
||||||
|
if ((ValueName == NULL) || (*ValueName == 0))
|
||||||
|
{
|
||||||
|
/* delete default value */
|
||||||
|
if (Key->Data != NULL)
|
||||||
|
free(Key->Data);
|
||||||
|
Key->Data = NULL;
|
||||||
|
Key->DataSize = 0;
|
||||||
|
Key->DataType = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* delete non-default value */
|
||||||
|
Ptr = Key->ValueList.Flink;
|
||||||
|
while (Ptr != &Key->ValueList)
|
||||||
|
{
|
||||||
|
Value = CONTAINING_RECORD(Ptr,
|
||||||
|
VALUE,
|
||||||
|
ValueList);
|
||||||
|
if (strcmp(Value->Name, ValueName) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &Key->ValueList)
|
||||||
|
return(ERROR_INVALID_PARAMETER);
|
||||||
|
|
||||||
|
/* delete value */
|
||||||
|
if (Value->Name != NULL)
|
||||||
|
free(Value->Name);
|
||||||
|
Value->Name = NULL;
|
||||||
|
Value->NameSize = 0;
|
||||||
|
|
||||||
|
if (Value->DataSize > sizeof(PUCHAR))
|
||||||
|
{
|
||||||
|
if (Value->Data != NULL)
|
||||||
|
free(Value->Data);
|
||||||
|
}
|
||||||
|
Value->Data = NULL;
|
||||||
|
Value->DataSize = 0;
|
||||||
|
Value->DataType = 0;
|
||||||
|
|
||||||
|
RemoveEntryList(&Value->ValueList);
|
||||||
|
free(Value);
|
||||||
|
}
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegEnumValue(HKEY Key,
|
||||||
|
ULONG Index,
|
||||||
|
PCHAR ValueName,
|
||||||
|
PULONG NameSize,
|
||||||
|
PULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
PULONG DataSize)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Ptr;
|
||||||
|
PVALUE Value;
|
||||||
|
ULONG Count = 0;
|
||||||
|
|
||||||
|
if (Key->Data != NULL)
|
||||||
|
{
|
||||||
|
if (Index > 0)
|
||||||
|
{
|
||||||
|
Index--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* enumerate default value */
|
||||||
|
if (ValueName != NULL)
|
||||||
|
*ValueName = 0;
|
||||||
|
if (Type != NULL)
|
||||||
|
*Type = Key->DataType;
|
||||||
|
if (DataSize != NULL)
|
||||||
|
*DataSize = Key->DataSize;
|
||||||
|
|
||||||
|
/* FIXME: return more values */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr = Key->ValueList.Flink;
|
||||||
|
while (Ptr != &Key->ValueList)
|
||||||
|
{
|
||||||
|
if (Index == Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Count++;
|
||||||
|
Ptr = Ptr->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ptr == &Key->ValueList)
|
||||||
|
return(ERROR_NO_MORE_ITEMS);
|
||||||
|
|
||||||
|
Value = CONTAINING_RECORD(Ptr,
|
||||||
|
VALUE,
|
||||||
|
ValueList);
|
||||||
|
|
||||||
|
/* FIXME: return values */
|
||||||
|
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
LONG
|
||||||
|
RegQueryMultipleValue(HKEY Key,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
return(ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
297
reactos/tools/mkhive/registry.h
Normal file
297
reactos/tools/mkhive/registry.h
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 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: registry.h,v 1.1 2003/04/14 17:18:48 ekohl Exp $
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS hive maker
|
||||||
|
* FILE: tools/mkhive/registry.h
|
||||||
|
* PURPOSE: Registry code
|
||||||
|
* PROGRAMMER: Eric Kohl
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __REGISTRY_H__
|
||||||
|
#define __REGISTRY_H__
|
||||||
|
|
||||||
|
|
||||||
|
#define INVALID_HANDLE_VALUE NULL
|
||||||
|
|
||||||
|
typedef struct _LIST_ENTRY
|
||||||
|
{
|
||||||
|
struct _LIST_ENTRY *Flink;
|
||||||
|
struct _LIST_ENTRY *Blink;
|
||||||
|
} LIST_ENTRY, *PLIST_ENTRY;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _REG_KEY
|
||||||
|
{
|
||||||
|
LIST_ENTRY KeyList;
|
||||||
|
LIST_ENTRY SubKeyList;
|
||||||
|
LIST_ENTRY ValueList;
|
||||||
|
|
||||||
|
ULONG NameSize;
|
||||||
|
PUCHAR Name;
|
||||||
|
|
||||||
|
/* default data */
|
||||||
|
ULONG DataType;
|
||||||
|
ULONG DataSize;
|
||||||
|
PUCHAR Data;
|
||||||
|
} KEY, *HKEY, **PHKEY;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _REG_VALUE
|
||||||
|
{
|
||||||
|
LIST_ENTRY ValueList;
|
||||||
|
|
||||||
|
/* value name */
|
||||||
|
ULONG NameSize;
|
||||||
|
PUCHAR Name;
|
||||||
|
|
||||||
|
/* value data */
|
||||||
|
ULONG DataType;
|
||||||
|
ULONG DataSize;
|
||||||
|
PUCHAR Data;
|
||||||
|
} VALUE, *PVALUE;
|
||||||
|
|
||||||
|
|
||||||
|
#define ERROR_SUCCESS 0L
|
||||||
|
#define ERROR_PATH_NOT_FOUND 2L
|
||||||
|
#define ERROR_OUTOFMEMORY 14L
|
||||||
|
#define ERROR_INVALID_PARAMETER 87L
|
||||||
|
#define ERROR_MORE_DATA 234L
|
||||||
|
#define ERROR_NO_MORE_ITEMS 259L
|
||||||
|
|
||||||
|
|
||||||
|
#define assert(x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* InitializeListHead (
|
||||||
|
* PLIST_ENTRY ListHead
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* FUNCTION: Initializes a double linked list
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ListHead = Caller supplied storage for the head of the list
|
||||||
|
*/
|
||||||
|
#define InitializeListHead(ListHead) \
|
||||||
|
{ \
|
||||||
|
(ListHead)->Flink = (ListHead); \
|
||||||
|
(ListHead)->Blink = (ListHead); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* InsertHeadList (
|
||||||
|
* PLIST_ENTRY ListHead,
|
||||||
|
* PLIST_ENTRY Entry
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* FUNCTION: Inserts an entry in a double linked list
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ListHead = Head of the list
|
||||||
|
* Entry = Entry to insert
|
||||||
|
*/
|
||||||
|
#define InsertHeadList(ListHead, ListEntry) \
|
||||||
|
{ \
|
||||||
|
PLIST_ENTRY OldFlink; \
|
||||||
|
OldFlink = (ListHead)->Flink; \
|
||||||
|
(ListEntry)->Flink = OldFlink; \
|
||||||
|
(ListEntry)->Blink = (ListHead); \
|
||||||
|
OldFlink->Blink = (ListEntry); \
|
||||||
|
(ListHead)->Flink = (ListEntry); \
|
||||||
|
assert((ListEntry) != NULL); \
|
||||||
|
assert((ListEntry)->Blink!=NULL); \
|
||||||
|
assert((ListEntry)->Blink->Flink == (ListEntry)); \
|
||||||
|
assert((ListEntry)->Flink != NULL); \
|
||||||
|
assert((ListEntry)->Flink->Blink == (ListEntry)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VOID
|
||||||
|
* InsertTailList (
|
||||||
|
* PLIST_ENTRY ListHead,
|
||||||
|
* PLIST_ENTRY Entry
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Inserts an entry in a double linked list
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ListHead = Head of the list
|
||||||
|
* Entry = Entry to insert
|
||||||
|
*/
|
||||||
|
#define InsertTailList(ListHead, ListEntry) \
|
||||||
|
{ \
|
||||||
|
PLIST_ENTRY OldBlink; \
|
||||||
|
OldBlink = (ListHead)->Blink; \
|
||||||
|
(ListEntry)->Flink = (ListHead); \
|
||||||
|
(ListEntry)->Blink = OldBlink; \
|
||||||
|
OldBlink->Flink = (ListEntry); \
|
||||||
|
(ListHead)->Blink = (ListEntry); \
|
||||||
|
assert((ListEntry) != NULL); \
|
||||||
|
assert((ListEntry)->Blink != NULL); \
|
||||||
|
assert((ListEntry)->Blink->Flink == (ListEntry)); \
|
||||||
|
assert((ListEntry)->Flink != NULL); \
|
||||||
|
assert((ListEntry)->Flink->Blink == (ListEntry)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BOOLEAN
|
||||||
|
* IsListEmpty (
|
||||||
|
* PLIST_ENTRY ListHead
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Checks if a double linked list is empty
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ListHead = Head of the list
|
||||||
|
*/
|
||||||
|
#define IsListEmpty(ListHead) \
|
||||||
|
((ListHead)->Flink == (ListHead))
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*VOID
|
||||||
|
*RemoveEntryList (
|
||||||
|
* PLIST_ENTRY Entry
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* FUNCTION:
|
||||||
|
* Removes an entry from a double linked list
|
||||||
|
*
|
||||||
|
* ARGUMENTS:
|
||||||
|
* ListEntry = Entry to remove
|
||||||
|
*/
|
||||||
|
#define RemoveEntryList(ListEntry) \
|
||||||
|
{ \
|
||||||
|
PLIST_ENTRY OldFlink; \
|
||||||
|
PLIST_ENTRY OldBlink; \
|
||||||
|
assert((ListEntry) != NULL); \
|
||||||
|
assert((ListEntry)->Blink!=NULL); \
|
||||||
|
assert((ListEntry)->Blink->Flink == (ListEntry)); \
|
||||||
|
assert((ListEntry)->Flink != NULL); \
|
||||||
|
assert((ListEntry)->Flink->Blink == (ListEntry)); \
|
||||||
|
OldFlink = (ListEntry)->Flink; \
|
||||||
|
OldBlink = (ListEntry)->Blink; \
|
||||||
|
OldFlink->Blink = OldBlink; \
|
||||||
|
OldBlink->Flink = OldFlink; \
|
||||||
|
(ListEntry)->Flink = NULL; \
|
||||||
|
(ListEntry)->Blink = NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: Returns the byte offset of a field within a structure
|
||||||
|
*/
|
||||||
|
#define FIELD_OFFSET(Type,Field) (LONG)(&(((Type *)(0))->Field))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PURPOSE: Returns the base address structure if the caller knows the
|
||||||
|
* address of a field within the structure
|
||||||
|
* ARGUMENTS:
|
||||||
|
* Address = address of the field
|
||||||
|
* Type = Type of the whole structure
|
||||||
|
* Field = Name of the field whose address is none
|
||||||
|
*/
|
||||||
|
#define CONTAINING_RECORD(Address,Type,Field) \
|
||||||
|
(Type *)(((LONG)Address) - FIELD_OFFSET(Type,Field))
|
||||||
|
|
||||||
|
|
||||||
|
#define REG_NONE 0
|
||||||
|
#define REG_SZ 1
|
||||||
|
#define REG_EXPAND_SZ 2
|
||||||
|
#define REG_BINARY 3
|
||||||
|
#define REG_DWORD 4
|
||||||
|
#define REG_DWORD_BIG_ENDIAN 5
|
||||||
|
#define REG_DWORD_LITTLE_ENDIAN 4
|
||||||
|
#define REG_LINK 6
|
||||||
|
#define REG_MULTI_SZ 7
|
||||||
|
#define REG_RESOURCE_LIST 8
|
||||||
|
#define REG_FULL_RESOURCE_DESCRIPTOR 9
|
||||||
|
#define REG_RESOURCE_REQUIREMENTS_LIST 10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
RegInitializeRegistry(VOID);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegCreateKey(HKEY ParentKey,
|
||||||
|
PCHAR KeyName,
|
||||||
|
PHKEY Key);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegDeleteKey(HKEY Key,
|
||||||
|
PCHAR Name);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegEnumKey(HKEY Key,
|
||||||
|
ULONG Index,
|
||||||
|
PCHAR Name,
|
||||||
|
PULONG NameSize);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegOpenKey(HKEY ParentKey,
|
||||||
|
PCHAR KeyName,
|
||||||
|
PHKEY Key);
|
||||||
|
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegSetValue(HKEY Key,
|
||||||
|
PCHAR ValueName,
|
||||||
|
ULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
ULONG DataSize);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegQueryValue(HKEY Key,
|
||||||
|
PCHAR ValueName,
|
||||||
|
PULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
PULONG DataSize);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegDeleteValue(HKEY Key,
|
||||||
|
PCHAR ValueName);
|
||||||
|
|
||||||
|
LONG
|
||||||
|
RegEnumValue(HKEY Key,
|
||||||
|
ULONG Index,
|
||||||
|
PCHAR ValueName,
|
||||||
|
PULONG NameSize,
|
||||||
|
PULONG Type,
|
||||||
|
PUCHAR Data,
|
||||||
|
PULONG DataSize);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
BOOL
|
||||||
|
RegImportTextHive(PCHAR ChunkBase,
|
||||||
|
U32 ChunkSize);
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
RegImportBinaryHive(PCHAR ChunkBase,
|
||||||
|
U32 ChunkSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __REGISTRY_H__ */
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue