From 7a1bc8eaca569bace6785b8c3fef91cc93156c26 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 26 Nov 2001 22:33:20 +0000 Subject: [PATCH] Added system hive support. svn path=/trunk/; revision=2395 --- freeldr/freeldr/reactos/hwdetect.c | 27 ++ freeldr/freeldr/reactos/reactos.c | 530 +++++++++++++++++++++++++ freeldr/freeldr/reactos/reactos.h | 28 ++ freeldr/freeldr/reactos/reghive.c | 510 ++++++++++++++++++++++++ freeldr/freeldr/reactos/registry.c | 596 +++++++++++++++++++++++++++++ freeldr/freeldr/reactos/registry.h | 287 ++++++++++++++ 6 files changed, 1978 insertions(+) create mode 100644 freeldr/freeldr/reactos/hwdetect.c create mode 100644 freeldr/freeldr/reactos/reactos.c create mode 100644 freeldr/freeldr/reactos/reactos.h create mode 100644 freeldr/freeldr/reactos/reghive.c create mode 100644 freeldr/freeldr/reactos/registry.c create mode 100644 freeldr/freeldr/reactos/registry.h diff --git a/freeldr/freeldr/reactos/hwdetect.c b/freeldr/freeldr/reactos/hwdetect.c new file mode 100644 index 00000000000..10b1c12038c --- /dev/null +++ b/freeldr/freeldr/reactos/hwdetect.c @@ -0,0 +1,27 @@ +/* + * 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 diff --git a/freeldr/freeldr/reactos/reactos.c b/freeldr/freeldr/reactos/reactos.c new file mode 100644 index 00000000000..05ac2bf4b76 --- /dev/null +++ b/freeldr/freeldr/reactos/reactos.c @@ -0,0 +1,530 @@ +/* + * FreeLoader + * + * Copyright (C) 1999, 2000, 2001 Brian Palmer + * + * 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(); +} + diff --git a/freeldr/freeldr/reactos/reactos.h b/freeldr/freeldr/reactos/reactos.h new file mode 100644 index 00000000000..fb907a3c8a7 --- /dev/null +++ b/freeldr/freeldr/reactos/reactos.h @@ -0,0 +1,28 @@ +/* + * FreeLoader + * + * Copyright (C) 1999, 2000 Brian Palmer + * + * 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 diff --git a/freeldr/freeldr/reactos/reghive.c b/freeldr/freeldr/reactos/reghive.c new file mode 100644 index 00000000000..d93daffbfbe --- /dev/null +++ b/freeldr/freeldr/reactos/reghive.c @@ -0,0 +1,510 @@ +/* + * 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 */ diff --git a/freeldr/freeldr/reactos/registry.c b/freeldr/freeldr/reactos/registry.c new file mode 100644 index 00000000000..f027b953aca --- /dev/null +++ b/freeldr/freeldr/reactos/registry.c @@ -0,0 +1,596 @@ +/* + * 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 */ diff --git a/freeldr/freeldr/reactos/registry.h b/freeldr/freeldr/reactos/registry.h new file mode 100644 index 00000000000..f10b144cba8 --- /dev/null +++ b/freeldr/freeldr/reactos/registry.h @@ -0,0 +1,287 @@ +/* + * 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 */ +