Fixed severe bugs in the default value handling of RegSetValue() and RegQueryValue().

Implemented simple registry links.
Added creation of the CurrentControlSet link.

svn path=/trunk/; revision=3132
This commit is contained in:
Eric Kohl 2002-06-20 16:31:59 +00:00
parent 669dabbc82
commit 27a682e098
3 changed files with 228 additions and 53 deletions

View file

@ -175,19 +175,21 @@ LoadBootDrivers(PCHAR szSystemRoot, int nPos)
rc = RegOpenKey(NULL, rc = RegOpenKey(NULL,
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder", "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
&hGroupKey); &hGroupKey);
DbgPrint((DPRINT_REACTOS, "RegOpenKey(): rc %d\n", (int)rc));
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return; {
DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder key (rc %d)\n", (int)rc));
return;
}
/* enumerate drivers */ /* enumerate drivers */
rc = RegOpenKey(NULL, rc = RegOpenKey(NULL,
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services", "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
&hServiceKey); &hServiceKey);
DbgPrint((DPRINT_REACTOS, "RegOpenKey(): rc %d\n", (int)rc));
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return; {
DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc));
DbgPrint((DPRINT_REACTOS, "hServiceKey: %x\n", (int)hServiceKey)); return;
}
BufferSize = sizeof(ValueBuffer); BufferSize = sizeof(ValueBuffer);
rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)ValueBuffer, &BufferSize); rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)ValueBuffer, &BufferSize);
@ -248,18 +250,18 @@ LoadBootDrivers(PCHAR szSystemRoot, int nPos)
{ {
DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath)); DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
} }
DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath)); DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath));
if (nPos < 100) if (nPos < 100)
nPos += 5; nPos += 5;
LoadDriver(ImagePath, nPos); LoadDriver(ImagePath, nPos);
} }
else else
{ {
DbgPrint((DPRINT_REACTOS, " Skipping driver '%s' with Start %d and Group '%s' (Current group '%s')\n", DbgPrint((DPRINT_REACTOS, " Skipping driver '%s' with Start %d and Group '%s' (Current group '%s')\n",
ImagePath, StartValue, DriverGroup, GroupName)); ImagePath, StartValue, DriverGroup, GroupName));
} }
Index++; Index++;
} }
@ -373,6 +375,7 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
char* Base; char* Base;
ULONG Size; ULONG Size;
// //
// Open the operating system section // Open the operating system section
// specified in the .ini file // specified in the .ini file
@ -454,7 +457,6 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
DebugPrint(DPRINT_REACTOS,"SystemRoot: '%s'", szBootPath); DebugPrint(DPRINT_REACTOS,"SystemRoot: '%s'", szBootPath);
UiDrawBackdrop(); UiDrawBackdrop();
UiDrawStatusText("Loading..."); UiDrawStatusText("Loading...");
UiDrawProgressBarCenter(0, 100); UiDrawProgressBarCenter(0, 100);
@ -584,7 +586,6 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
RegImportHive(Base, Size); RegImportHive(Base, Size);
UiDrawProgressBarCenter(15, 100); UiDrawProgressBarCenter(15, 100);
DebugPrint(DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size); DebugPrint(DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size);
/* /*
@ -598,6 +599,11 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
#endif #endif
UiDrawProgressBarCenter(20, 100); UiDrawProgressBarCenter(20, 100);
/*
* Initialize the 'currentControlSet' link
*/
RegInitCurrentControlSet(FALSE);
/* /*
* Load NLS files * Load NLS files
*/ */
@ -638,3 +644,4 @@ LoadAndBootReactOS(PUCHAR OperatingSystemName)
boot_reactos(); boot_reactos();
} }
/* EOF */

View file

@ -1,7 +1,7 @@
/* /*
* FreeLoader * FreeLoader
* *
* Copyright (C) 2001 Eric Kohl * Copyright (C) 2001, 2002 Eric Kohl
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -31,6 +31,8 @@
#include <debug.h> #include <debug.h>
#include "registry.h" #include "registry.h"
#include <ui.h>
static HKEY RootKey; static HKEY RootKey;
@ -47,12 +49,122 @@ RegInitializeRegistry(VOID)
RootKey->Name = (PUCHAR)MmAllocateMemory(2); RootKey->Name = (PUCHAR)MmAllocateMemory(2);
strcpy(RootKey->Name, "\\"); strcpy(RootKey->Name, "\\");
RootKey->Type = 0; RootKey->DataType = 0;
RootKey->DataSize = 0; RootKey->DataSize = 0;
RootKey->Data = NULL; RootKey->Data = NULL;
} }
LONG
RegInitCurrentControlSet(BOOL LastKnownGood)
{
CHAR ControlSetKeyName[80];
HKEY SelectKey;
HKEY SystemKey;
HKEY ControlSetKey;
HKEY LinkKey;
ULONG CurrentSet = 0;
ULONG DefaultSet = 0;
ULONG LastKnownGoodSet = 0;
ULONG DataSize;
LONG Error;
Error = RegOpenKey(NULL,
"\\Registry\\Machine\\SYSTEM\\Select",
&SelectKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegOpenKey() failed (Error %u)\n", (int)Error));
return(Error);
}
DataSize = sizeof(ULONG);
Error = RegQueryValue(SelectKey,
"Default",
NULL,
(PUCHAR)&DefaultSet,
&DataSize);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegQueryValue('Default') failed (Error %u)\n", (int)Error));
return(Error);
}
DataSize = sizeof(ULONG);
Error = RegQueryValue(SelectKey,
"LastKnownGood",
NULL,
(PUCHAR)&LastKnownGoodSet,
&DataSize);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegQueryValue('Default') failed (Error %u)\n", (int)Error));
return(Error);
}
CurrentSet = (LastKnownGood == TRUE) ? LastKnownGoodSet : DefaultSet;
strcpy(ControlSetKeyName, "ControlSet");
switch(CurrentSet)
{
case 1:
strcat(ControlSetKeyName, "001");
break;
case 2:
strcat(ControlSetKeyName, "002");
break;
case 3:
strcat(ControlSetKeyName, "003");
break;
case 4:
strcat(ControlSetKeyName, "004");
break;
case 5:
strcat(ControlSetKeyName, "005");
break;
}
Error = RegOpenKey(NULL,
"\\Registry\\Machine\\SYSTEM",
&SystemKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegOpenKey(SystemKey) failed (Error %u)\n", (int)Error));
return(Error);
}
Error = RegOpenKey(SystemKey,
ControlSetKeyName,
&ControlSetKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegOpenKey(ControlSetKey) failed (Error %u)\n", (int)Error));
return(Error);
}
Error = RegCreateKey(SystemKey,
"CurrentControlSet",
&LinkKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegCreateKey(LinkKey) failed (Error %u)\n", (int)Error));
return(Error);
}
Error = RegSetValue(LinkKey,
NULL,
REG_LINK,
(PUCHAR)&ControlSetKey,
sizeof(PVOID));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_REGISTRY, "RegSetValue(LinkKey) failed (Error %u)\n", (int)Error));
return(Error);
}
return(ERROR_SUCCESS);
}
LONG LONG
RegCreateKey(HKEY ParentKey, RegCreateKey(HKEY ParentKey,
PCHAR KeyName, PCHAR KeyName,
@ -67,7 +179,7 @@ RegCreateKey(HKEY ParentKey,
int subkeyLength; int subkeyLength;
int stringLength; int stringLength;
DbgPrint((DPRINT_REGISTRY, "KeyName '%s'\n", KeyName)); DbgPrint((DPRINT_REGISTRY, "KeyName '%s'\n", KeyName));
if (*KeyName == '\\') if (*KeyName == '\\')
{ {
@ -83,10 +195,15 @@ RegCreateKey(HKEY ParentKey,
CurrentKey = ParentKey; CurrentKey = ParentKey;
} }
/* Check whether current key is a link */
if (CurrentKey->DataType == REG_LINK)
{
CurrentKey = (HKEY)CurrentKey->Data;
}
while (*KeyName != 0) while (*KeyName != 0)
{ {
DbgPrint((DPRINT_REGISTRY, "KeyName '%s'\n", KeyName)); DbgPrint((DPRINT_REGISTRY, "KeyName '%s'\n", KeyName));
if (*KeyName == '\\') if (*KeyName == '\\')
KeyName++; KeyName++;
@ -107,13 +224,13 @@ RegCreateKey(HKEY ParentKey,
Ptr = CurrentKey->SubKeyList.Flink; Ptr = CurrentKey->SubKeyList.Flink;
while (Ptr != &CurrentKey->SubKeyList) while (Ptr != &CurrentKey->SubKeyList)
{ {
DbgPrint((DPRINT_REGISTRY, "Ptr 0x%x\n", Ptr)); DbgPrint((DPRINT_REGISTRY, "Ptr 0x%x\n", Ptr));
SearchKey = CONTAINING_RECORD(Ptr, SearchKey = CONTAINING_RECORD(Ptr,
KEY, KEY,
KeyList); KeyList);
DbgPrint((DPRINT_REGISTRY, "SearchKey 0x%x\n", SearchKey)); DbgPrint((DPRINT_REGISTRY, "SearchKey 0x%x\n", SearchKey));
DbgPrint((DPRINT_REGISTRY, "Searching '%s'\n", SearchKey->Name)); DbgPrint((DPRINT_REGISTRY, "Searching '%s'\n", SearchKey->Name));
if (strncmp(SearchKey->Name, name, subkeyLength) == 0) if (strncmp(SearchKey->Name, name, subkeyLength) == 0)
break; break;
@ -130,7 +247,7 @@ RegCreateKey(HKEY ParentKey,
InitializeListHead(&NewKey->SubKeyList); InitializeListHead(&NewKey->SubKeyList);
InitializeListHead(&NewKey->ValueList); InitializeListHead(&NewKey->ValueList);
NewKey->Type = 0; NewKey->DataType = 0;
NewKey->DataSize = 0; NewKey->DataSize = 0;
NewKey->Data = NULL; NewKey->Data = NULL;
@ -142,14 +259,20 @@ RegCreateKey(HKEY ParentKey,
memcpy(NewKey->Name, name, subkeyLength); memcpy(NewKey->Name, name, subkeyLength);
NewKey->Name[subkeyLength] = 0; NewKey->Name[subkeyLength] = 0;
DbgPrint((DPRINT_REGISTRY, "NewKey 0x%x\n", NewKey)); DbgPrint((DPRINT_REGISTRY, "NewKey 0x%x\n", NewKey));
DbgPrint((DPRINT_REGISTRY, "NewKey '%s' Length %d\n", NewKey->Name, NewKey->NameSize)); DbgPrint((DPRINT_REGISTRY, "NewKey '%s' Length %d\n", NewKey->Name, NewKey->NameSize));
CurrentKey = NewKey; CurrentKey = NewKey;
} }
else else
{ {
CurrentKey = SearchKey; CurrentKey = SearchKey;
/* Check whether current key is a link */
if (CurrentKey->DataType == REG_LINK)
{
CurrentKey = (HKEY)CurrentKey->Data;
}
} }
KeyName = KeyName + stringLength; KeyName = KeyName + stringLength;
@ -246,6 +369,11 @@ RegOpenKey(HKEY ParentKey,
CurrentKey = ParentKey; CurrentKey = ParentKey;
} }
/* Check whether current key is a link */
if (CurrentKey->DataType == REG_LINK)
{
CurrentKey = (HKEY)CurrentKey->Data;
}
while (*KeyName != 0) while (*KeyName != 0)
{ {
@ -270,14 +398,14 @@ RegOpenKey(HKEY ParentKey,
Ptr = CurrentKey->SubKeyList.Flink; Ptr = CurrentKey->SubKeyList.Flink;
while (Ptr != &CurrentKey->SubKeyList) while (Ptr != &CurrentKey->SubKeyList)
{ {
DbgPrint((DPRINT_REGISTRY, "Ptr 0x%x\n", Ptr)); DbgPrint((DPRINT_REGISTRY, "Ptr 0x%x\n", Ptr));
SearchKey = CONTAINING_RECORD(Ptr, SearchKey = CONTAINING_RECORD(Ptr,
KEY, KEY,
KeyList); KeyList);
DbgPrint((DPRINT_REGISTRY, "SearchKey 0x%x\n", SearchKey)); DbgPrint((DPRINT_REGISTRY, "SearchKey 0x%x\n", SearchKey));
DbgPrint((DPRINT_REGISTRY, "Searching '%s'\n", SearchKey->Name)); DbgPrint((DPRINT_REGISTRY, "Searching '%s'\n", SearchKey->Name));
if (strncmp(SearchKey->Name, name, subkeyLength) == 0) if (strncmp(SearchKey->Name, name, subkeyLength) == 0)
break; break;
@ -292,6 +420,12 @@ RegOpenKey(HKEY ParentKey,
else else
{ {
CurrentKey = SearchKey; CurrentKey = SearchKey;
/* Check whether current key is a link */
if (CurrentKey->DataType == REG_LINK)
{
CurrentKey = (HKEY)CurrentKey->Data;
}
} }
KeyName = KeyName + stringLength; KeyName = KeyName + stringLength;
@ -320,12 +454,24 @@ RegSetValue(HKEY Key,
if ((ValueName == NULL) || (*ValueName == 0)) if ((ValueName == NULL) || (*ValueName == 0))
{ {
/* set default value */ /* set default value */
if (Key->Data != NULL) if ((Key->Data != NULL) && (Key->DataSize > sizeof(PUCHAR)))
MmFreeMemory(Key->Data); {
Key->Data = (PUCHAR)MmAllocateMemory(DataSize); MmFreeMemory(Key->Data);
Key->DataSize = DataSize; }
Key->Type = Type;
memcpy(Key->Data, Data, DataSize); if (DataSize <= sizeof(PUCHAR))
{
Key->DataSize = DataSize;
Key->DataType = Type;
memcpy(&Key->Data, Data, DataSize);
}
else
{
Key->Data = (PUCHAR)MmAllocateMemory(DataSize);
Key->DataSize = DataSize;
Key->DataType = Type;
memcpy(Key->Data, Data, DataSize);
}
} }
else else
{ {
@ -337,7 +483,7 @@ RegSetValue(HKEY Key,
VALUE, VALUE,
ValueList); ValueList);
DbgPrint((DPRINT_REGISTRY, "Value->Name '%s'\n", Value->Name)); DbgPrint((DPRINT_REGISTRY, "Value->Name '%s'\n", Value->Name));
if (stricmp(Value->Name, ValueName) == 0) if (stricmp(Value->Name, ValueName) == 0)
break; break;
@ -348,7 +494,7 @@ RegSetValue(HKEY Key,
if (Ptr == &Key->ValueList) if (Ptr == &Key->ValueList)
{ {
/* add new value */ /* add new value */
DbgPrint((DPRINT_REGISTRY, "No value found - adding new value\n")); DbgPrint((DPRINT_REGISTRY, "No value found - adding new value\n"));
Value = (PVALUE)MmAllocateMemory(sizeof(VALUE)); Value = (PVALUE)MmAllocateMemory(sizeof(VALUE));
if (Value == NULL) if (Value == NULL)
@ -359,25 +505,30 @@ RegSetValue(HKEY Key,
if (Value->Name == NULL) if (Value->Name == NULL)
return(ERROR_OUTOFMEMORY); return(ERROR_OUTOFMEMORY);
strcpy(Value->Name, ValueName); strcpy(Value->Name, ValueName);
Value->DataType = REG_NONE;
Value->DataSize = 0;
Value->Data = NULL; Value->Data = NULL;
} }
/* set new value */ /* set new value */
if ((Value->Data != NULL) && (Value->DataSize > sizeof(PUCHAR)))
{
MmFreeMemory(Value->Data);
}
if (DataSize <= sizeof(PUCHAR)) if (DataSize <= sizeof(PUCHAR))
{ {
Value->DataSize = DataSize; Value->DataSize = DataSize;
Value->Type = Type; Value->DataType = Type;
memcpy(&Value->Data, Data, DataSize); memcpy(&Value->Data, Data, DataSize);
} }
else else
{ {
if(Value->Data != NULL)
MmFreeMemory(Value->Data);
Value->Data = (PUCHAR)MmAllocateMemory(DataSize); Value->Data = (PUCHAR)MmAllocateMemory(DataSize);
if (Value->Data == NULL) if (Value->Data == NULL)
return(ERROR_OUTOFMEMORY); return(ERROR_OUTOFMEMORY);
Value->DataType = Type;
Value->DataSize = DataSize; Value->DataSize = DataSize;
Value->Type = Type;
memcpy(Value->Data, Data, DataSize); memcpy(Value->Data, Data, DataSize);
} }
} }
@ -403,12 +554,25 @@ RegQueryValue(HKEY Key,
return(ERROR_INVALID_PARAMETER); return(ERROR_INVALID_PARAMETER);
if (Type != NULL) if (Type != NULL)
*Type = Key->Type; *Type = Key->DataType;
if ((Data != NULL) && (DataSize != NULL)) if ((Data != NULL) && (DataSize != NULL))
{ {
Size = min(Key->DataSize, *DataSize); if (Key->DataSize <= sizeof(PUCHAR))
memcpy(Data, Key->Data, Size); {
*DataSize = Size; Size = min(Key->DataSize, *DataSize);
memcpy(Data, &Key->Data, Size);
*DataSize = Size;
}
else
{
Size = min(Key->DataSize, *DataSize);
memcpy(Data, Key->Data, Size);
*DataSize = Size;
}
}
else if ((Data == NULL) && (DataSize != NULL))
{
*DataSize = Key->DataSize;
} }
} }
else else
@ -421,7 +585,7 @@ RegQueryValue(HKEY Key,
VALUE, VALUE,
ValueList); ValueList);
DbgPrint((DPRINT_REGISTRY, "Searching for '%s'. Value name '%s'\n", ValueName, Value->Name)); DbgPrint((DPRINT_REGISTRY, "Searching for '%s'. Value name '%s'\n", ValueName, Value->Name));
if (stricmp(Value->Name, ValueName) == 0) if (stricmp(Value->Name, ValueName) == 0)
break; break;
@ -433,7 +597,7 @@ RegQueryValue(HKEY Key,
return(ERROR_INVALID_PARAMETER); return(ERROR_INVALID_PARAMETER);
if (Type != NULL) if (Type != NULL)
*Type = Value->Type; *Type = Value->DataType;
if ((Data != NULL) && (DataSize != NULL)) if ((Data != NULL) && (DataSize != NULL))
{ {
if (Value->DataSize <= sizeof(PUCHAR)) if (Value->DataSize <= sizeof(PUCHAR))
@ -449,6 +613,10 @@ RegQueryValue(HKEY Key,
*DataSize = Size; *DataSize = Size;
} }
} }
else if ((Data == NULL) && (DataSize != NULL))
{
*DataSize = Value->DataSize;
}
} }
return(ERROR_SUCCESS); return(ERROR_SUCCESS);
@ -469,7 +637,7 @@ RegDeleteValue(HKEY Key,
MmFreeMemory(Key->Data); MmFreeMemory(Key->Data);
Key->Data = NULL; Key->Data = NULL;
Key->DataSize = 0; Key->DataSize = 0;
Key->Type = 0; Key->DataType = 0;
} }
else else
{ {
@ -502,7 +670,7 @@ RegDeleteValue(HKEY Key,
} }
Value->Data = NULL; Value->Data = NULL;
Value->DataSize = 0; Value->DataSize = 0;
Value->Type = 0; Value->DataType = 0;
RemoveEntryList(&Value->ValueList); RemoveEntryList(&Value->ValueList);
MmFreeMemory(Value); MmFreeMemory(Value);
@ -536,7 +704,7 @@ RegEnumValue(HKEY Key,
if (ValueName != NULL) if (ValueName != NULL)
*ValueName = 0; *ValueName = 0;
if (Type != NULL) if (Type != NULL)
*Type = Key->Type; *Type = Key->DataType;
if (DataSize != NULL) if (DataSize != NULL)
*DataSize = Key->DataSize; *DataSize = Key->DataSize;

View file

@ -40,7 +40,7 @@ typedef struct _REG_KEY
PUCHAR Name; PUCHAR Name;
/* default data */ /* default data */
ULONG Type; ULONG DataType;
ULONG DataSize; ULONG DataSize;
PUCHAR Data; PUCHAR Data;
} KEY, *HKEY, **PHKEY; } KEY, *HKEY, **PHKEY;
@ -55,7 +55,7 @@ typedef struct _REG_VALUE
PUCHAR Name; PUCHAR Name;
/* value data */ /* value data */
ULONG Type; ULONG DataType;
ULONG DataSize; ULONG DataSize;
PUCHAR Data; PUCHAR Data;
} VALUE, *PVALUE; } VALUE, *PVALUE;
@ -207,9 +207,6 @@ typedef struct _REG_VALUE
(Type *)(((LONG)Address) - FIELD_OFFSET(Type,Field)) (Type *)(((LONG)Address) - FIELD_OFFSET(Type,Field))
//typedef struct _REG_KEY *HKEY, **PHKEY;
#define REG_NONE 0 #define REG_NONE 0
#define REG_SZ 1 #define REG_SZ 1
#define REG_EXPAND_SZ 2 #define REG_EXPAND_SZ 2
@ -228,6 +225,9 @@ typedef struct _REG_VALUE
VOID VOID
RegInitializeRegistry(VOID); RegInitializeRegistry(VOID);
LONG
RegInitCurrentControlSet(BOOL LastKnownGood);
LONG LONG
RegCreateKey(HKEY ParentKey, RegCreateKey(HKEY ParentKey,