--- /dev/null
+/*
+ * FreeLoader
+ *
+ * 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 "../freeldr.h"
+
+
+VOID
+DetectHardware(VOID)
+{
+}
\ No newline at end of file
--- /dev/null
+/*
+ * FreeLoader
+ *
+ * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
+ *
+ * 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 "../freeldr.h"
+#include "../asmcode.h"
+#include "reactos.h"
+#include "../stdlib.h"
+#include "../fs.h"
+#include "../tui.h"
+#include "../multiboot.h"
+#include "../arcname.h"
+#include "../memory.h"
+#include "../parseini.h"
+
+#include "registry.h"
+
+
+#define NDEBUG
+
+
+static BOOL
+LoadKernel(PCHAR szFileName, int nPos)
+{
+ PFILE FilePointer;
+ PCHAR szShortName;
+ char szBuffer[256];
+
+ szShortName = strrchr(szFileName, '\\');
+ if (szShortName == NULL)
+ szShortName = szFileName;
+ else
+ szShortName = szShortName + 1;
+
+ FilePointer = OpenFile(szFileName);
+ if (FilePointer == NULL)
+ {
+ strcat(szBuffer, szShortName);
+ strcat(szBuffer, " not found.");
+ MessageBox(szBuffer);
+ return(FALSE);
+ }
+
+ /*
+ * Update the status bar with the current file
+ */
+ strcpy(szBuffer, " Reading ");
+ strcat(szBuffer, szShortName);
+ DrawStatusText(szBuffer);
+
+ /*
+ * Load the kernel
+ */
+ MultiBootLoadKernel(FilePointer);
+
+ DrawProgressBar(nPos);
+
+ return(TRUE);
+}
+
+
+static BOOL
+LoadDriver(PCHAR szFileName, int nPos)
+{
+ PFILE FilePointer;
+ char value[256];
+ char *p;
+
+ FilePointer = OpenFile(szFileName);
+ if (FilePointer == NULL)
+ {
+ strcat(value, szFileName);
+ strcat(value, " not found.");
+ MessageBox(value);
+ return(FALSE);
+ }
+
+ /*
+ * Update the status bar with the current file
+ */
+ strcpy(value, " Reading ");
+ p = strrchr(szFileName, '\\');
+ if (p == NULL)
+ strcat(value, szFileName);
+ else
+ strcat(value, p + 1);
+ while (strlen(value) < 80)
+ strcat(value, " ");
+ DrawStatusText(value);
+
+ /*
+ * Load the driver
+ */
+ MultiBootLoadModule(FilePointer, szFileName, NULL);
+
+ DrawProgressBar(nPos);
+
+ return(TRUE);
+}
+
+
+static VOID
+LoadBootDrivers(PCHAR szSystemRoot, int nPos)
+{
+ LONG rc = 0;
+ HKEY hGroupKey, hServiceKey, hDriverKey;
+ char ValueBuffer[256];
+ char ServiceName[256];
+ ULONG BufferSize;
+ ULONG Index;
+ char *s, *p;
+ char GroupName[256];
+ ULONG len;
+ BOOL done;
+
+ ULONG ValueSize;
+ ULONG ValueType;
+ ULONG StartValue;
+ UCHAR DriverGroup[256];
+ ULONG DriverGroupSize;
+
+ UCHAR ImagePath[256];
+
+ /* get 'service group order' key */
+ rc = RegOpenKey(NULL,
+ "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
+ &hGroupKey);
+// printf("RegOpenKey(): rc %d\n", (int)rc);
+ if (rc != ERROR_SUCCESS)
+ return;
+
+ /* enumerate drivers */
+ rc = RegOpenKey(NULL,
+ "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
+ &hServiceKey);
+// printf("RegOpenKey(): rc %d\n", (int)rc);
+ if (rc != ERROR_SUCCESS)
+ return;
+
+// printf("hKey: %x\n", (int)hKey);
+
+ BufferSize = 256;
+ rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)ValueBuffer, &BufferSize);
+// printf("RegQueryValue(): rc %d\n", (int)rc);
+ if (rc != ERROR_SUCCESS)
+ return;
+
+
+// printf("BufferSize: %d \n", (int)BufferSize);
+
+// printf("ValueBuffer: '%s' \n", ValueBuffer);
+
+ done = FALSE;
+ s = ValueBuffer;
+ do
+ {
+ p = strchr(s, ';');
+ if (p != NULL)
+ {
+ len = p - s;
+ memcpy(GroupName, s, len);
+ GroupName[len] = 0;
+ s = p + 1;
+ }
+ else
+ {
+ strcpy(GroupName, s);
+ done = TRUE;
+ }
+// printf("Driver group: '%s'\n", GroupName);
+
+ /* enumerate all drivers */
+ Index = 0;
+ while (TRUE)
+ {
+ ValueSize = 256;
+ rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
+// printf("RegEnumKey(): rc %d\n", (int)rc);
+ if (rc == ERROR_NO_MORE_ITEMS)
+ break;
+ if (rc != ERROR_SUCCESS)
+ return;
+// printf("Service %d: '%s'\n", (int)Index, ServiceName);
+
+ /* open driver Key */
+ rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
+
+ ValueSize = sizeof(ULONG);
+ rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
+// printf(" Start: %x \n", (int)StartValue);
+
+ DriverGroupSize = 256;
+ rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
+// printf(" Group: %s \n", DriverGroup);
+
+ if ((StartValue == 0) && (stricmp(DriverGroup, GroupName) == 0))
+ {
+ ValueSize = 256;
+ rc = RegQueryValue(hDriverKey,
+ "ImagePathName",
+ NULL,
+ (PUCHAR)ImagePath,
+ &ValueSize);
+ if (rc != ERROR_SUCCESS)
+ {
+// printf(" ImagePath: not found\n");
+ strcpy(ImagePath, szSystemRoot);
+ strcat(ImagePath, "system32\\drivers\\");
+ strcat(ImagePath, ServiceName);
+ strcat(ImagePath, ".sys");
+ }
+ else
+ {
+// printf(" ImagePath: '%s'\n", ImagePath);
+ }
+// printf(" Loading driver: '%s'\n", ImagePath);
+
+ LoadDriver(ImagePath, nPos);
+
+ if (nPos < 100)
+ nPos += 5;
+ }
+ Index++;
+ }
+ }
+ while(done == FALSE);
+
+}
+
+void LoadAndBootReactOS(PUCHAR OperatingSystemName)
+{
+ PFILE FilePointer;
+ char name[1024];
+ char value[1024];
+ char szFileName[1024];
+ char szBootPath[256];
+// int i;
+// int nNumDriverFiles=0;
+// int nNumFilesLoaded=0;
+ char MsgBuffer[256];
+ ULONG SectionId;
+
+ char* Base;
+ ULONG Size;
+
+ //
+ // Open the operating system section
+ // specified in the .ini file
+ //
+ if (!OpenSection(OperatingSystemName, &SectionId))
+ {
+ sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
+ MessageBox(MsgBuffer);
+ return;
+ }
+
+ /*
+ * 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();
+ mb_info.mem_upper = GetExtendedMemorySize();
+ mb_info.boot_device = 0xffffffff;
+ mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
+ mb_info.mods_count = 0;
+ mb_info.mods_addr = (unsigned long)multiboot_modules;
+ mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
+ if (mb_info.mmap_length)
+ {
+ mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
+ mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
+ //printf("memory map length: %d\n", mb_info.mmap_length);
+ //printf("dumping memory map:\n");
+ //for (i=0; i<(mb_info.mmap_length / 4); i++)
+ //{
+ // printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
+ //}
+ //getch();
+ }
+ //printf("low_mem = %d\n", mb_info.mem_lower);
+ //printf("high_mem = %d\n", mb_info.mem_upper);
+ //getch();
+
+ /*
+ * Make sure the system path is set in the .ini file
+ */
+ if (!ReadSectionSettingByName(SectionId, "SystemPath", value, 1024))
+ {
+ MessageBox("System path not specified for selected operating system.");
+ return;
+ }
+
+ /*
+ * Verify system path
+ */
+ if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
+ {
+ sprintf(MsgBuffer,"Invalid system path: '%s'", value);
+ MessageBox(MsgBuffer);
+ return;
+ }
+
+ /* set boot drive and partition */
+ ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
+ ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
+
+ /* copy ARC path into kernel command line */
+ strcpy(multiboot_kernel_cmdline, value);
+
+ /*
+ * Read the optional kernel parameters (if any)
+ */
+ if (ReadSectionSettingByName(SectionId, "Options", value, 1024))
+ {
+ strcat(multiboot_kernel_cmdline, " ");
+ strcat(multiboot_kernel_cmdline, value);
+ }
+
+ /* append a backslash */
+ if ((strlen(szBootPath)==0) ||
+ szBootPath[strlen(szBootPath)] != '\\')
+ strcat(szBootPath, "\\");
+
+#ifndef NDEBUG
+ sprintf(MsgBuffer,"SystemRoot: '%s'", szBootPath);
+ MessageBox(MsgBuffer);
+#endif
+
+ DrawBackdrop();
+
+ DrawStatusText(" Loading...");
+ DrawProgressBar(0);
+
+ /*
+ * Try to open boot drive
+ */
+ if (!OpenDiskDrive(BootDrive, BootPartition))
+ {
+ MessageBox("Failed to open boot drive.");
+ return;
+ }
+
+ /*
+ * Find the kernel image name
+ * and try to load the kernel off the disk
+ */
+ if(ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
+ {
+ /*
+ * Set the name and
+ */
+ if (value[0] == '\\')
+ {
+ strcpy(szFileName, value);
+ }
+ else
+ {
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\");
+ strcat(szFileName, value);
+ }
+ }
+ else
+ {
+ strcpy(value, "NTOSKRNL.EXE");
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\");
+ strcat(szFileName, value);
+ }
+
+ if (!LoadKernel(szFileName, 5))
+ return;
+
+ /*
+ * Find the HAL image name
+ * and try to load the kernel off the disk
+ */
+ if(ReadSectionSettingByName(SectionId, "Hal", value, 1024))
+ {
+ /*
+ * Set the name and
+ */
+ if (value[0] == '\\')
+ {
+ strcpy(szFileName, value);
+ }
+ else
+ {
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\");
+ strcat(szFileName, value);
+ }
+ }
+ else
+ {
+ strcpy(value, "HAL.DLL");
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\");
+ strcat(szFileName, value);
+ }
+
+ if (!LoadDriver(szFileName, 10))
+ return;
+
+ /*
+ * Find the System hive image name
+ * and try to load it off the disk
+ */
+ if(ReadSectionSettingByName(SectionId, "SystemHive", value, 1024))
+ {
+ /*
+ * Set the name and
+ */
+ if (value[0] == '\\')
+ {
+ strcpy(szFileName, value);
+ }
+ else
+ {
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\CONFIG\\");
+ strcat(szFileName, value);
+ }
+ }
+ else
+ {
+ strcpy(value, "SYSTEM.HIV");
+ strcpy(szFileName, szBootPath);
+ strcat(szFileName, "SYSTEM32\\CONFIG\\");
+ strcat(szFileName, value);
+ }
+
+#ifndef NDEBUG
+ sprintf(MsgBuffer,"SystemHive: '%s'", szFileName);
+ MessageBox(MsgBuffer);
+#endif
+
+ FilePointer = OpenFile(szFileName);
+ if (FilePointer == NULL)
+ {
+ strcat(value, " not found.");
+ MessageBox(value);
+ return;
+ }
+
+ /*
+ * Update the status bar with the current file
+ */
+ strcpy(name, " Reading ");
+ strcat(name, value);
+ while (strlen(name) < 80)
+ strcat(name, " ");
+ DrawStatusText(name);
+
+ /*
+ * Load the system hive
+ */
+ Base = MultiBootLoadModule(FilePointer, szFileName, &Size);
+ RegInitializeRegistry();
+ RegImportHive(Base, Size);
+
+ DrawProgressBar(15);
+
+#ifndef NDEBUG
+ sprintf(MsgBuffer,"SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size);
+ MessageBox(MsgBuffer);
+#endif
+
+ /*
+ * retrieve hardware information and create the hardware hive
+ */
+// DetectHardware();
+// Base = MultiBootCreateModule(HARDWARE.HIV);
+// RegExportHardwareHive(Base, &Size);
+// MultiBootCloseModule(Base, Size);
+
+ DrawProgressBar(20);
+
+ /*
+ * load NLS files
+ */
+// LoadNlsFiles(szBootPath);
+
+ DrawProgressBar(25);
+
+ /*
+ * load boot drivers
+ */
+ LoadBootDrivers(szBootPath, 30);
+
+
+ /*
+ * Clear the screen and redraw the backdrop and status bar
+ */
+ DrawBackdrop();
+ DrawStatusText(" Press any key to boot");
+
+ /*
+ * Wait for user
+ */
+ strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
+ strcat(name, OperatingSystemName);
+ strcat(name, ".");
+ //MessageBox(name);
+
+ RestoreScreen(ScreenBuffer);
+
+ /*
+ * Now boot the kernel
+ */
+ stop_floppy();
+ boot_reactos();
+}
+
--- /dev/null
+/*
+ * FreeLoader
+ *
+ * Copyright (C) 1999, 2000 Brian Palmer <brianp@sginet.com>
+ *
+ * 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.
+ */
+
+#ifndef __REACTOS_H
+#define __REACTOS_H
+
+
+void LoadAndBootReactOS(PUCHAR OperatingSystemName);
+
+
+#endif // defined __REACTOS_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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 "../freeldr.h"
+#include "../stdlib.h"
+#include "../memory.h"
+
+#include "registry.h"
+
+#define NDEBUG
+
+
+#define REGISTRY_FILE_MAGIC "REGEDIT4"
+
+#define INVALID_HANDLE_VALUE NULL
+
+
+static PCHAR
+checkAndSkipMagic (PCHAR regChunk)
+{
+ if (strncmp (regChunk,
+ REGISTRY_FILE_MAGIC,
+ strlen (REGISTRY_FILE_MAGIC)) != 0)
+ {
+#ifndef NDEBUG
+ printf("incorrect magic number in registry chunk. expected: %s got:%.*s\n",
+ REGISTRY_FILE_MAGIC,
+ strlen (REGISTRY_FILE_MAGIC),
+ regChunk);
+#endif
+ return 0;
+ }
+ regChunk += strlen (REGISTRY_FILE_MAGIC);
+#ifndef NDEBUG
+ printf("Found registry chunk magic value\n");
+#endif
+
+ 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)
+ FreeMemory(*newKeyName);
+
+ *newKeyName = AllocateMemory(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;
+
+#ifndef NDEBUG
+ printf("Adding new key '%s'\n", newKeyName);
+#endif
+
+ RegCreateKey(NULL,
+ newKeyName,
+ &handleToReturn);
+
+#ifndef NDEBUG
+ printf(" returned handle: 0x%x\n", handleToReturn);
+#endif
+
+ 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
+ {
+// 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(DWORD);
+ while (*regChunk != 0 && isxdigit(*regChunk))
+ {
+ regChunk++;
+ }
+ }
+ else
+ {
+// UNIMPLEMENTED;
+ }
+
+ return dataSize;
+}
+
+static BOOL
+allocateDataBuffer (PVOID * data, int * dataBufferSize, int dataSize)
+{
+ if (*dataBufferSize < dataSize)
+ {
+ if (*dataBufferSize > 0)
+ FreeMemory(*data);
+ *data = AllocateMemory(dataSize);
+ *dataBufferSize = dataSize;
+ }
+
+ return TRUE;
+}
+
+static PCHAR
+getKeyValueDataFromChunk (PCHAR regChunk, PCHAR dataFormat, PCHAR data)
+{
+ char dataValue;
+ ULONG 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(ULONG));
+ }
+ else
+ {
+// UNIMPLEMENTED;
+ }
+
+ return *regChunk ? regChunk : 0;
+}
+
+static BOOL
+setKeyValue (HKEY currentKey,
+ PCHAR newValueName,
+ ULONG keyValueType,
+ PVOID data,
+ ULONG dataSize)
+{
+ LONG status;
+
+#ifndef NDEBUG
+ printf("Adding value (%s) to current key, with data type %d size %d\n",
+ newValueName,
+ (int)keyValueType,
+ (int)dataSize);
+#endif
+ status = RegSetValue(currentKey,
+ newValueName,
+ keyValueType,
+ data,
+ dataSize);
+ if (status != ERROR_SUCCESS)
+ {
+#ifndef NDEBUG
+ printf("could not set key value, rc:%d\n", status);
+#endif
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+VOID
+RegImportHive(PCHAR ChunkBase,
+ ULONG ChunkSize)
+{
+ HKEY currentKey = NULL;
+ int newKeySize = 0;
+ char *newKeyName = NULL;
+ char dataFormat [10];
+ int keyValueType;
+ int dataSize = 0;
+ int dataBufferSize = 0;
+ PVOID data = 0;
+ PCHAR regChunk;
+
+#ifndef NDEBUG
+ printf("ChunkBase 0x%x ChunkSize %x\n", ChunkBase, ChunkSize);
+#endif
+
+ regChunk = checkAndSkipMagic (ChunkBase);
+ if (regChunk == 0)
+ return;
+
+ while (regChunk != 0 && *regChunk != 0 && (((ULONG)regChunk-(ULONG)ChunkBase) < ChunkSize))
+ {
+ regChunk = skipWhitespaceInChunk (regChunk);
+ if (regChunk == 0)
+ continue;
+
+ if (*regChunk == '[')
+ {
+#ifndef NDEBUG
+ printf("Line: %s\n", regChunk);
+#endif
+ if (currentKey != NULL)
+ {
+#ifndef NDEBUG
+ printf("Closing current key: 0x%lx\n", currentKey);
+#endif
+ currentKey = NULL;
+ }
+
+ regChunk++;
+
+ newKeySize = computeKeyNameSize (regChunk);
+ if (!allocateKeyName (&newKeyName, newKeySize))
+ {
+ regChunk = 0;
+ continue;
+ }
+
+ regChunk = getKeyNameFromChunk (regChunk, newKeyName);
+ if (regChunk == 0)
+ continue;
+
+ currentKey = createNewKey (newKeyName);
+ if (currentKey == NULL)
+ {
+ regChunk = skipToNextKeyInChunk (regChunk);
+ continue;
+ }
+
+ regChunk++;
+ }
+ else
+ {
+ if (currentKey == NULL)
+ {
+ 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 (newKeyName != NULL)
+ {
+ FreeMemory(newKeyName);
+ }
+ if (data != NULL)
+ {
+ FreeMemory(data);
+ }
+
+ return;
+}
+
+/* EOF */
--- /dev/null
+/*
+ * FreeLoader
+ *
+ * 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.
+ */
+
+/*
+ * TODO:
+ * - Implement RegDeleteKey().
+ * - Implement RegQueryMultipleValue().
+ * - Fix RegEnumValue().
+ */
+
+#include "../freeldr.h"
+#include "../memory.h"
+#include "../stdlib.h"
+#include "registry.h"
+
+#define NDEBUG
+
+
+static HKEY RootKey;
+
+
+VOID
+RegInitializeRegistry(VOID)
+{
+ RootKey = (HKEY)AllocateMemory(sizeof(KEY));
+
+ InitializeListHead(&RootKey->SubKeyList);
+ InitializeListHead(&RootKey->ValueList);
+ InitializeListHead(&RootKey->KeyList);
+
+ RootKey->NameSize = 2;
+ RootKey->Name = (PUCHAR)AllocateMemory(2);
+ strcpy(RootKey->Name, "\\");
+
+ RootKey->Type = 0;
+ RootKey->DataSize = 0;
+ RootKey->Data = NULL;
+}
+
+
+LONG
+RegCreateKey(HKEY ParentKey,
+ PCHAR KeyName,
+ PHKEY Key)
+{
+ PLIST_ENTRY Ptr;
+ HKEY SearchKey;
+ HKEY CurrentKey;
+ HKEY NewKey;
+ PCHAR p;
+ PCHAR name;
+ int subkeyLength;
+ int stringLength;
+
+#ifndef NDEBUG
+ printf("RegCreateKey(%s) called\n", KeyName);
+#endif
+
+ if (*KeyName == '\\')
+ {
+ KeyName++;
+ CurrentKey = RootKey;
+ }
+ else if (ParentKey == NULL)
+ {
+ CurrentKey = RootKey;
+ }
+ else
+ {
+ CurrentKey = ParentKey;
+ }
+
+
+ while (*KeyName != 0)
+ {
+#ifndef NDEBUG
+ printf("RegCreateKey(): KeyName '%s'\n", KeyName);
+#endif
+ 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)
+ {
+#ifndef NDEBUG
+ printf("RegCreateKey(): Ptr 0x%x\n", Ptr);
+#endif
+ SearchKey = CONTAINING_RECORD(Ptr,
+ KEY,
+ KeyList);
+#ifndef NDEBUG
+ printf("RegCreateKey(): SearchKey 0x%x\n", SearchKey);
+ printf("RegCreateKey(): searching '%s'\n", SearchKey->Name);
+#endif
+ if (strncmp(SearchKey->Name, name, subkeyLength) == 0)
+ break;
+
+ Ptr = Ptr->Flink;
+ }
+
+ if (Ptr == &CurrentKey->SubKeyList)
+ {
+ /* no key found -> create new subkey */
+ NewKey = (HKEY)AllocateMemory(sizeof(KEY));
+ if (NewKey == NULL)
+ return(ERROR_OUTOFMEMORY);
+
+ InitializeListHead(&NewKey->SubKeyList);
+ InitializeListHead(&NewKey->ValueList);
+
+ NewKey->Type = 0;
+ NewKey->DataSize = 0;
+ NewKey->Data = NULL;
+
+ InsertTailList(&CurrentKey->SubKeyList, &NewKey->KeyList);
+ NewKey->NameSize = subkeyLength + 1;
+ NewKey->Name = (PCHAR)AllocateMemory(NewKey->NameSize);
+ if (NewKey->Name == NULL)
+ return(ERROR_OUTOFMEMORY);
+ memcpy(NewKey->Name, name, subkeyLength);
+ NewKey->Name[subkeyLength] = 0;
+
+#ifndef NDEBUG
+ printf("RegCreateKey(): new key 0x%x\n", NewKey);
+ printf("RegCreateKey(): new key '%s' length %d\n", NewKey->Name, NewKey->NameSize);
+#endif
+
+ CurrentKey = NewKey;
+ }
+ else
+ {
+ CurrentKey = SearchKey;
+ }
+
+ 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);
+
+#ifndef NDEBUG
+ printf("RegEnumKey(): name '%s' length %d\n", SearchKey->Name, SearchKey->NameSize);
+#endif
+
+ 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;
+ HKEY CurrentKey;
+ PCHAR p;
+ PCHAR name;
+ int subkeyLength;
+ int stringLength;
+
+#ifndef NDEBUG
+ printf("RegOpenKey(%s) called\n", KeyName);
+#endif
+
+ *Key = NULL;
+
+ if (*KeyName == '\\')
+ {
+ KeyName++;
+ CurrentKey = RootKey;
+ }
+ else if (ParentKey == NULL)
+ {
+ CurrentKey = RootKey;
+ }
+ else
+ {
+ CurrentKey = ParentKey;
+ }
+
+
+ while (*KeyName != 0)
+ {
+#ifndef NDEBUG
+ printf("RegOpenKey(): KeyName '%s'\n", KeyName);
+#endif
+ 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)
+ {
+#ifndef NDEBUG
+ printf("RegCreateKey(): Ptr 0x%x\n", Ptr);
+#endif
+ SearchKey = CONTAINING_RECORD(Ptr,
+ KEY,
+ KeyList);
+#ifndef NDEBUG
+ printf("RegOpenKey(): SearchKey 0x%x\n", SearchKey);
+ printf("RegOpenKey(): searching '%s'\n", SearchKey->Name);
+#endif
+ if (strncmp(SearchKey->Name, name, subkeyLength) == 0)
+ break;
+
+ Ptr = Ptr->Flink;
+ }
+
+ if (Ptr == &CurrentKey->SubKeyList)
+ {
+ return(ERROR_PATH_NOT_FOUND);
+ }
+ else
+ {
+ CurrentKey = SearchKey;
+ }
+
+ 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;
+
+#ifndef NDEBUG
+ printf("RegSetValue(%x, '%s', %d, %x, %d)\n", (int)Key, ValueName, (int)Type, (int)Data, (int)DataSize);
+#endif
+ if ((ValueName == NULL) || (*ValueName == 0))
+ {
+ /* set default value */
+ if (Key->Data != NULL)
+ FreeMemory(Key->Data);
+ Key->Data = (PUCHAR)AllocateMemory(DataSize);
+ Key->DataSize = DataSize;
+ Key->Type = 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);
+#ifndef NDEBUG
+ printf("Value->Name: '%s'\n", Value->Name);
+#endif
+ if (stricmp(Value->Name, ValueName) == 0)
+ break;
+
+ Ptr = Ptr->Flink;
+ }
+
+ if (Ptr == &Key->ValueList)
+ {
+ /* add new value */
+#ifndef NDEBUG
+ printf("No value found - adding new value\n");
+#endif
+ Value = (PVALUE)AllocateMemory(sizeof(VALUE));
+ if (Value == NULL)
+ return(ERROR_OUTOFMEMORY);
+ InsertTailList(&Key->ValueList, &Value->ValueList);
+ Value->NameSize = strlen(ValueName)+1;
+ Value->Name = (PCHAR)AllocateMemory(Value->NameSize);
+ if (Value->Name == NULL)
+ return(ERROR_OUTOFMEMORY);
+ strcpy(Value->Name, ValueName);
+ Value->Data = NULL;
+ }
+
+ /* set new value */
+ if (DataSize <= sizeof(PUCHAR))
+ {
+ Value->DataSize = DataSize;
+ Value->Type = Type;
+ memcpy(&Value->Data, Data, DataSize);
+ }
+ else
+ {
+ if(Value->Data != NULL)
+ FreeMemory(Value->Data);
+ Value->Data = (PUCHAR)AllocateMemory(DataSize);
+ if (Value->Data == NULL)
+ return(ERROR_OUTOFMEMORY);
+ Value->DataSize = DataSize;
+ Value->Type = Type;
+ 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;
+
+ if ((ValueName == NULL) || (*ValueName == 0))
+ {
+ /* query default value */
+ if (Key->Data == NULL)
+ return(ERROR_INVALID_PARAMETER);
+
+ if (Type != NULL)
+ *Type = Key->Type;
+ if ((Data != NULL) && (DataSize != NULL))
+ {
+ Size = min(Key->DataSize, *DataSize);
+ memcpy(Data, Key->Data, Size);
+ *DataSize = Size;
+ }
+ }
+ else
+ {
+ /* query non-default value */
+ Ptr = Key->ValueList.Flink;
+ while (Ptr != &Key->ValueList)
+ {
+ Value = CONTAINING_RECORD(Ptr,
+ VALUE,
+ ValueList);
+#ifndef NDEBUG
+ printf("Name: %s\n", Value->Name);
+#endif
+ if (stricmp(Value->Name, ValueName) == 0)
+ break;
+
+ Ptr = Ptr->Flink;
+ }
+
+ if (Ptr == &Key->ValueList)
+ return(ERROR_INVALID_PARAMETER);
+
+ if (Type != NULL)
+ *Type = Value->Type;
+ if ((Data != NULL) && (DataSize != NULL))
+ {
+ if (*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;
+ }
+ }
+ }
+
+ return(ERROR_SUCCESS);
+}
+
+
+LONG
+RegDeleteValue(HKEY Key,
+ PCHAR ValueName)
+{
+ PLIST_ENTRY Ptr;
+ PVALUE Value;
+
+ if ((ValueName == NULL) || (*ValueName == 0))
+ {
+ /* delete default value */
+ if (Key->Data != NULL)
+ FreeMemory(Key->Data);
+ Key->Data = NULL;
+ Key->DataSize = 0;
+ Key->Type = 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)
+ FreeMemory(Value->Name);
+ Value->Name = NULL;
+ Value->NameSize = 0;
+
+ if (Value->DataSize > sizeof(PUCHAR))
+ {
+ if (Value->Data != NULL)
+ FreeMemory(Value->Data);
+ }
+ Value->Data = NULL;
+ Value->DataSize = 0;
+ Value->Type = 0;
+
+ RemoveEntryList(&Value->ValueList);
+ FreeMemory(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->Type;
+ 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 */
--- /dev/null
+/*
+ * FreeLoader - registry.h
+ *
+ * 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.
+ */
+
+#ifndef __REGISTRY_H
+#define __REGISTRY_H
+
+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 Type;
+ ULONG DataSize;
+ PUCHAR Data;
+} KEY, *HKEY, **PHKEY;
+
+
+typedef struct _REG_VALUE
+{
+ LIST_ENTRY ValueList;
+
+ /* value name */
+ ULONG NameSize;
+ PUCHAR Name;
+
+ /* value data */
+ ULONG Type;
+ 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))
+
+
+//typedef struct _REG_KEY *HKEY, **PHKEY;
+
+
+#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);
+
+
+VOID
+RegImportHive(PCHAR ChunkBase,
+ ULONG ChunkSize);
+
+
+#endif /* __REGISTRY_H */
+
+/* EOF */
+