mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
Added system hive support.
svn path=/trunk/; revision=2395
This commit is contained in:
parent
0aee7968ad
commit
7a1bc8eaca
6 changed files with 1978 additions and 0 deletions
27
freeldr/freeldr/reactos/hwdetect.c
Normal file
27
freeldr/freeldr/reactos/hwdetect.c
Normal file
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
530
freeldr/freeldr/reactos/reactos.c
Normal file
530
freeldr/freeldr/reactos/reactos.c
Normal file
|
@ -0,0 +1,530 @@
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
|
28
freeldr/freeldr/reactos/reactos.h
Normal file
28
freeldr/freeldr/reactos/reactos.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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
|
510
freeldr/freeldr/reactos/reghive.c
Normal file
510
freeldr/freeldr/reactos/reghive.c
Normal file
|
@ -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 */
|
596
freeldr/freeldr/reactos/registry.c
Normal file
596
freeldr/freeldr/reactos/registry.c
Normal file
|
@ -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 */
|
287
freeldr/freeldr/reactos/registry.h
Normal file
287
freeldr/freeldr/reactos/registry.h
Normal file
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue