Implemented registry links (REG_LINK).

Create the 'CurrentControlSet' link after the registry has been initialized.

svn path=/trunk/; revision=3130
This commit is contained in:
Eric Kohl 2002-06-19 22:32:47 +00:00
parent 5c4728ed0a
commit 79d575aef4
8 changed files with 683 additions and 405 deletions

View file

@ -87,9 +87,6 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION
UCHAR Data[1]; UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; } KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
#define REG_OPTION_CREATE_LINK 0x00000002
#define REG_OPTION_BACKUP_RESTORE 0x00000004
/* used by [Nt/Zw]QueryMultipleValueKey */ /* used by [Nt/Zw]QueryMultipleValueKey */

View file

@ -1,4 +1,4 @@
/* $Id: registry.h,v 1.2 2001/05/30 19:58:48 ekohl Exp $ /* $Id: registry.h,v 1.3 2002/06/19 22:30:29 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -14,27 +14,30 @@
#define __INCLUDE_NTOS_REGISTRY_H #define __INCLUDE_NTOS_REGISTRY_H
/* Key access rights */ /* Key access rights */
#define KEY_QUERY_VALUE (1) #define KEY_QUERY_VALUE (1)
#define KEY_SET_VALUE (2) #define KEY_SET_VALUE (2)
#define KEY_CREATE_SUB_KEY (4) #define KEY_CREATE_SUB_KEY (4)
#define KEY_ENUMERATE_SUB_KEYS (8) #define KEY_ENUMERATE_SUB_KEYS (8)
#define KEY_NOTIFY (16) #define KEY_NOTIFY (16)
#define KEY_CREATE_LINK (32) #define KEY_CREATE_LINK (32)
#define KEY_READ (0x20019L) #define KEY_READ (0x20019L)
#define KEY_WRITE (0x20006L) #define KEY_WRITE (0x20006L)
#define KEY_EXECUTE (0x20019L) #define KEY_EXECUTE (0x20019L)
#define KEY_ALL_ACCESS (0xf003fL) #define KEY_ALL_ACCESS (0xf003fL)
/* Key create options */
#define REG_OPTION_NON_VOLATILE (0x0L)
#define REG_OPTION_VOLATILE (0x1L)
#define REG_OPTION_CREATE_LINK (0x2L)
#define REG_OPTION_BACKUP_RESTORE (0x8L)
#define REG_OPTION_OPEN_LINK (0x8L)
/* RegCreateKeyEx */ /* Key create/open disposition */
#define REG_OPTION_VOLATILE (0x1L) #define REG_CREATED_NEW_KEY (0x1L)
#define REG_OPTION_NON_VOLATILE (0L) #define REG_OPENED_EXISTING_KEY (0x2L)
#define REG_CREATED_NEW_KEY (0x1L)
#define REG_OPENED_EXISTING_KEY (0x2L)
/* Value types */
/* RegEnumValue */
#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)

View file

@ -26,6 +26,21 @@
#define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM" #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
#define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY" #define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY"
#define REG_BLOCK_SIZE 4096
#define REG_HBIN_DATA_OFFSET 32
#define REG_BIN_ID 0x6e696268
#define REG_INIT_BLOCK_LIST_SIZE 32
#define REG_INIT_HASH_TABLE_SIZE 3
#define REG_EXTEND_HASH_TABLE_SIZE 4
#define REG_VALUE_LIST_CELL_MULTIPLE 4
#define REG_KEY_CELL_ID 0x6b6e
#define REG_HASH_TABLE_BLOCK_ID 0x666c
#define REG_VALUE_CELL_ID 0x6b76
#define REG_LINK_KEY_CELL_TYPE 0x10
#define REG_KEY_CELL_TYPE 0x20
#define REG_ROOT_KEY_CELL_TYPE 0x2c
#define REG_HIVE_ID 0x66676572
#define REGISTRY_FILE_MAGIC "REGEDIT4" #define REGISTRY_FILE_MAGIC "REGEDIT4"
#define REG_MACHINE_STD_HANDLE_NAME "HKEY_LOCAL_MACHINE" #define REG_MACHINE_STD_HANDLE_NAME "HKEY_LOCAL_MACHINE"
@ -247,6 +262,7 @@ typedef struct _REGISTRY_HIVE
atempts to access the key must not succeed */ atempts to access the key must not succeed */
#define KO_MARKED_FOR_DELETE 0x00000001 #define KO_MARKED_FOR_DELETE 0x00000001
/* Type defining the Object Manager Key Object */ /* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT typedef struct _KEY_OBJECT
{ {
@ -294,6 +310,9 @@ typedef struct _KEY_OBJECT
extern BOOLEAN CmiDoVerify; extern BOOLEAN CmiDoVerify;
extern PREGISTRY_HIVE CmiVolatileHive;
extern POBJECT_TYPE CmiKeyType;
extern KSPIN_LOCK CmiKeyListLock;
VOID VOID

View file

@ -32,11 +32,11 @@ NtCreateKey(OUT PHANDLE KeyHandle,
IN ULONG CreateOptions, IN ULONG CreateOptions,
OUT PULONG Disposition) OUT PULONG Disposition)
{ {
UNICODE_STRING RemainingPath; UNICODE_STRING RemainingPath;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
NTSTATUS Status; NTSTATUS Status;
PVOID Object; PVOID Object;
PWSTR End; PWSTR End;
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n", DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
ObjectAttributes->ObjectName, ObjectAttributes->ObjectName,
@ -48,34 +48,34 @@ NtCreateKey(OUT PHANDLE KeyHandle,
Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType); Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return Status;
} }
DPRINT("RemainingPath %wZ\n", &RemainingPath); DPRINT("RemainingPath %wZ\n", &RemainingPath);
if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0)) if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0))
{ {
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{ {
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (Disposition) if (Disposition)
*Disposition = REG_OPENED_EXISTING_KEY; *Disposition = REG_OPENED_EXISTING_KEY;
Status = ObCreateHandle(PsGetCurrentProcess(), Status = ObCreateHandle(PsGetCurrentProcess(),
Object, Object,
DesiredAccess, DesiredAccess,
FALSE, FALSE,
KeyHandle); KeyHandle);
DPRINT("Status %x\n", Status); DPRINT("Status %x\n", Status);
ObDereferenceObject(Object); ObDereferenceObject(Object);
return Status; return Status;
} }
/* If RemainingPath contains \ we must return error /* If RemainingPath contains \ we must return error
because NtCreateKey don't create trees */ because NtCreateKey don't create trees */
@ -85,21 +85,21 @@ NtCreateKey(OUT PHANDLE KeyHandle,
End = wcschr(RemainingPath.Buffer, '\\'); End = wcschr(RemainingPath.Buffer, '\\');
if (End != NULL) if (End != NULL)
{ {
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object); DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object);
Status = ObCreateObject(KeyHandle, Status = ObCreateObject(KeyHandle,
DesiredAccess, DesiredAccess,
NULL, NULL,
CmiKeyType, CmiKeyType,
(PVOID*) &KeyObject); (PVOID*)&KeyObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return(Status); return(Status);
KeyObject->ParentKey = Object; KeyObject->ParentKey = Object;
@ -115,13 +115,13 @@ NtCreateKey(OUT PHANDLE KeyHandle,
// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql); // KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql);
/* add key to subkeys of parent if needed */ /* add key to subkeys of parent if needed */
Status = CmiAddSubKey(KeyObject->RegistryHive, Status = CmiAddSubKey(KeyObject->RegistryHive,
KeyObject->ParentKey, KeyObject->ParentKey,
KeyObject, KeyObject,
RemainingPath.Buffer, RemainingPath.Buffer,
RemainingPath.Length, RemainingPath.Length,
TitleIndex, TitleIndex,
Class, Class,
CreateOptions); CreateOptions);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -134,21 +134,21 @@ NtCreateKey(OUT PHANDLE KeyHandle,
KeyObject->NameSize = KeyObject->KeyCell->NameSize; KeyObject->NameSize = KeyObject->KeyCell->NameSize;
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive) if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
{ {
KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->BlockOffset; KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->BlockOffset;
KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset; KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
} }
else else
{ {
KeyObject->KeyCell->ParentKeyOffset = -1; KeyObject->KeyCell->ParentKeyOffset = -1;
KeyObject->KeyCell->SecurityKeyOffset = -1; KeyObject->KeyCell->SecurityKeyOffset = -1;
/* This key must rest in memory unless it is deleted /* This key must rest in memory unless it is deleted
or file is unloaded */ or file is unloaded */
ObReferenceObjectByPointer(KeyObject, ObReferenceObjectByPointer(KeyObject,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
NULL, NULL,
UserMode); UserMode);
} }
CmiAddKeyToList(KeyObject->ParentKey, KeyObject); CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql); // KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql);
@ -807,61 +807,59 @@ END FIXME*/
NTSTATUS STDCALL NTSTATUS STDCALL
NtOpenKey(OUT PHANDLE KeyHandle, NtOpenKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes) IN POBJECT_ATTRIBUTES ObjectAttributes)
{ {
UNICODE_STRING RemainingPath; UNICODE_STRING RemainingPath;
NTSTATUS Status; NTSTATUS Status;
PVOID Object; PVOID Object;
DPRINT("KH %x DA %x OA %x OA->ON %x\n", DPRINT("KH %x DA %x OA %x OA->ON %x\n",
KeyHandle, KeyHandle,
DesiredAccess, DesiredAccess,
ObjectAttributes, ObjectAttributes,
ObjectAttributes ? ObjectAttributes->ObjectName : NULL); ObjectAttributes ? ObjectAttributes->ObjectName : NULL);
RemainingPath.Buffer = NULL;
Status = ObFindObject(ObjectAttributes,
&Object,
&RemainingPath,
CmiKeyType);
RemainingPath.Buffer = NULL;
Status = ObFindObject(ObjectAttributes,
&Object,
&RemainingPath,
CmiKeyType);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return(Status);
} }
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object); VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer); DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
{ {
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return(STATUS_UNSUCCESSFUL);
} }
/* Fail if the key has been deleted */ /* Fail if the key has been deleted */
if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE) if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE)
{ {
ObDereferenceObject(Object); ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL; return(STATUS_UNSUCCESSFUL);
} }
Status = ObCreateHandle( Status = ObCreateHandle(PsGetCurrentProcess(),
PsGetCurrentProcess(), Object,
Object, DesiredAccess,
DesiredAccess, FALSE,
FALSE, KeyHandle);
KeyHandle); ObDereferenceObject(Object);
ObDereferenceObject(Object);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return Status; return(Status);
} }
return STATUS_SUCCESS; return(STATUS_SUCCESS);
} }
@ -1185,13 +1183,12 @@ NtQueryValueKey(IN HANDLE KeyHandle,
NTSTATUS STDCALL NTSTATUS STDCALL
NtSetValueKey( NtSetValueKey(IN HANDLE KeyHandle,
IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName,
IN PUNICODE_STRING ValueName, IN ULONG TitleIndex,
IN ULONG TitleIndex, IN ULONG Type,
IN ULONG Type, IN PVOID Data,
IN PVOID Data, IN ULONG DataSize)
IN ULONG DataSize)
{ {
NTSTATUS Status; NTSTATUS Status;
PKEY_OBJECT KeyObject; PKEY_OBJECT KeyObject;
@ -1203,6 +1200,7 @@ NtSetValueKey(
PDATA_CELL DataCell; PDATA_CELL DataCell;
PDATA_CELL NewDataCell; PDATA_CELL NewDataCell;
PHBIN pBin; PHBIN pBin;
ULONG DesiredAccess;
// KIRQL OldIrql; // KIRQL OldIrql;
DPRINT("KeyHandle %x ValueName %S Type %d\n", DPRINT("KeyHandle %x ValueName %S Type %d\n",
@ -1211,13 +1209,17 @@ NtSetValueKey(
wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1); wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
ValueName2[ValueName->Length>>1] = 0; ValueName2[ValueName->Length>>1] = 0;
DesiredAccess = KEY_SET_VALUE;
if (Type == REG_LINK)
DesiredAccess |= KEY_CREATE_LINK;
/* Verify that the handle is valid and is a registry key */ /* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle, Status = ObReferenceObjectByHandle(KeyHandle,
KEY_SET_VALUE, DesiredAccess,
CmiKeyType, CmiKeyType,
UserMode, UserMode,
(PVOID *) &KeyObject, (PVOID *)&KeyObject,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return(Status); return(Status);
@ -1311,6 +1313,11 @@ NtSetValueKey(
ValueCell->DataOffset = NewOffset; ValueCell->DataOffset = NewOffset;
} }
if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
{
KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
}
/* Update time of heap */ /* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin)) if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
{ {

View file

@ -21,21 +21,6 @@
#include "cm.h" #include "cm.h"
#define REG_BLOCK_SIZE 4096
#define REG_HBIN_DATA_OFFSET 32
#define REG_BIN_ID 0x6e696268
#define REG_INIT_BLOCK_LIST_SIZE 32
#define REG_INIT_HASH_TABLE_SIZE 3
#define REG_EXTEND_HASH_TABLE_SIZE 4
#define REG_VALUE_LIST_CELL_MULTIPLE 4
#define REG_KEY_CELL_ID 0x6b6e
#define REG_HASH_TABLE_BLOCK_ID 0x666c
#define REG_VALUE_CELL_ID 0x6b76
#define REG_KEY_CELL_TYPE 0x20
#define REG_ROOT_KEY_CELL_TYPE 0x2c
#define REG_HIVE_ID 0x66676572
extern PREGISTRY_HIVE CmiVolatileHive;
BOOLEAN CmiDoVerify = FALSE; BOOLEAN CmiDoVerify = FALSE;
@ -1067,11 +1052,11 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
&NKBOffset); &NKBOffset);
if (NewKeyCell == NULL) if (NewKeyCell == NULL)
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
NewKeyCell->Id = REG_KEY_CELL_ID; NewKeyCell->Id = REG_KEY_CELL_ID;
NewKeyCell->Type = REG_KEY_CELL_TYPE; NewKeyCell->Type = REG_KEY_CELL_TYPE;
ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime); ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime);
@ -1339,12 +1324,11 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
NTSTATUS NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
IN PKEY_CELL KeyCell, IN PKEY_CELL KeyCell,
IN PCHAR ValueName) IN PCHAR ValueName)
{ {
PVALUE_LIST_CELL ValueListCell; PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell; PVALUE_CELL CurValueCell;
PHBIN pBin;
ULONG i; ULONG i;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL); ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
@ -1358,7 +1342,7 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
for (i = 0; i < KeyCell->NumberOfValues; i++) for (i = 0; i < KeyCell->NumberOfValues; i++)
{ {
CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], &pBin); CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
if ((CurValueCell != NULL) && if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == strlen(ValueName)) && (CurValueCell->NameSize == strlen(ValueName)) &&
(memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0)) (memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0))
@ -1376,8 +1360,6 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
KeyCell->NumberOfValues -= 1; KeyCell->NumberOfValues -= 1;
CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]); CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]);
/* update time of heap */
ZwQuerySystemTime((PTIME) &pBin->DateModified);
break; break;
} }
CmiReleaseBlock(RegistryHive, CurValueCell); CmiReleaseBlock(RegistryHive, CurValueCell);
@ -1409,15 +1391,15 @@ CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
HBOffset); HBOffset);
if ((NewHashBlock == NULL) || (!NT_SUCCESS(Status))) if ((NewHashBlock == NULL) || (!NT_SUCCESS(Status)))
{ {
Status = STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
} }
else else
{ {
NewHashBlock->Id = REG_HASH_TABLE_BLOCK_ID; NewHashBlock->Id = REG_HASH_TABLE_BLOCK_ID;
NewHashBlock->HashTableSize = HashTableSize; NewHashBlock->HashTableSize = HashTableSize;
*HashBlock = NewHashBlock; *HashBlock = NewHashBlock;
} }
return Status; return Status;
} }
@ -1864,6 +1846,9 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive,
BLOCK_OFFSET BlockOffset, BLOCK_OFFSET BlockOffset,
PHBIN * ppBin) PHBIN * ppBin)
{ {
if (ppBin)
*ppBin = NULL;
if ((BlockOffset == 0) || (BlockOffset == -1)) if ((BlockOffset == 0) || (BlockOffset == -1))
return NULL; return NULL;

View file

@ -1,4 +1,4 @@
/* $Id: registry.c,v 1.72 2002/06/16 11:45:06 ekohl Exp $ /* $Id: registry.c,v 1.73 2002/06/19 22:31:33 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -42,6 +42,10 @@ VOID
CmiCheckKey(BOOLEAN Verbose, CmiCheckKey(BOOLEAN Verbose,
HANDLE Key); HANDLE Key);
static NTSTATUS
CmiCreateCurrentControlSetLink(VOID);
/* FUNCTIONS ****************************************************************/
VOID VOID
CmiCheckSubKeys(BOOLEAN Verbose, CmiCheckSubKeys(BOOLEAN Verbose,
@ -471,7 +475,9 @@ CmInit2(PCHAR CommandLine)
/* FIXME: Store current command line */ /* FIXME: Store current command line */
/* FIXME: Create the 'CurrentControlSet' link. */ /* Create the 'CurrentControlSet' link. */
CmiCreateCurrentControlSetLink();
/* Set PICE 'Start' value to 1, if PICE debugging is enabled */ /* Set PICE 'Start' value to 1, if PICE debugging is enabled */
PiceStart = 4; PiceStart = 4;
@ -505,6 +511,100 @@ CmInit2(PCHAR CommandLine)
} }
static NTSTATUS
CmiCreateCurrentControlSetLink(VOID)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[5];
WCHAR TargetNameBuffer[80];
ULONG TargetNameLength;
UNICODE_STRING LinkName;
UNICODE_STRING LinkValue;
ULONG CurrentSet;
ULONG DefaultSet;
ULONG Failed;
ULONG LastKnownGood;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle;
DPRINT("CmiCreateCurrentControlSetLink() called\n");
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
QueryTable[0].Name = L"Current";
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[0].EntryContext = &CurrentSet;
QueryTable[1].Name = L"Default";
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[1].EntryContext = &DefaultSet;
QueryTable[2].Name = L"Failed";
QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[2].EntryContext = &Failed;
QueryTable[3].Name = L"LastKnownGood";
QueryTable[3].Flags = RTL_QUERY_REGISTRY_DIRECT;
QueryTable[3].EntryContext = &LastKnownGood;
Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
L"\\Registry\\Machine\\SYSTEM\\Select",
QueryTable,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DPRINT("Current %ld Default %ld\n", CurrentSet, DefaultSet);
swprintf(TargetNameBuffer,
L"\\Registry\\Machine\\SYSTEM\\ControlSet%03lu",
CurrentSet);
TargetNameLength = wcslen(TargetNameBuffer) * sizeof(WCHAR);
DPRINT("Link target '%S'\n", TargetNameBuffer);
RtlInitUnicodeString(&LinkName,
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet");
InitializeObjectAttributes(&ObjectAttributes,
&LinkName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK,
NULL,
NULL);
Status = NtCreateKey(&KeyHandle,
KEY_ALL_ACCESS | KEY_CREATE_LINK,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
return(Status);
}
RtlInitUnicodeString(&LinkValue,
L"SymbolicLinkValue");
Status=NtSetValueKey(KeyHandle,
&LinkValue,
0,
REG_LINK,
(PVOID)TargetNameBuffer,
TargetNameLength);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
}
NtClose(KeyHandle);
return(Status);
}
NTSTATUS NTSTATUS
CmiConnectHive(PWSTR FileName, CmiConnectHive(PWSTR FileName,
PWSTR FullName, PWSTR FullName,

View file

@ -13,151 +13,246 @@
#include <string.h> #include <string.h>
#include <internal/pool.h> #include <internal/pool.h>
#include <internal/registry.h> #include <internal/registry.h>
#include <ntos/minmax.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
#include "cm.h" #include "cm.h"
extern POBJECT_TYPE CmiKeyType;
extern KSPIN_LOCK CmiKeyListLock; static NTSTATUS
CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath);
/* FUNCTONS *****************************************************************/
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectParse(PVOID ParsedObject, CmiObjectParse(PVOID ParsedObject,
PVOID *NextObject, PVOID *NextObject,
PUNICODE_STRING FullPath, PUNICODE_STRING FullPath,
PWSTR *Path, PWSTR *Path,
POBJECT_TYPE ObjectType, POBJECT_TYPE ObjectType,
ULONG Attributes) ULONG Attributes)
{ {
BLOCK_OFFSET BlockOffset; BLOCK_OFFSET BlockOffset;
PKEY_OBJECT FoundObject; PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey; PKEY_OBJECT ParsedKey;
PKEY_CELL SubKeyCell; PKEY_CELL SubKeyCell;
CHAR cPath[MAX_PATH]; CHAR cPath[MAX_PATH];
NTSTATUS Status; NTSTATUS Status;
PWSTR end; PWSTR end;
UNICODE_STRING LinkPath;
UNICODE_STRING TargetPath;
ParsedKey = ParsedObject; ParsedKey = ParsedObject;
VERIFY_KEY_OBJECT(ParsedKey); VERIFY_KEY_OBJECT(ParsedKey);
*NextObject = NULL; *NextObject = NULL;
if ((*Path) == NULL) if ((*Path) == NULL)
{
DPRINT("*Path is NULL\n");
return STATUS_UNSUCCESSFUL;
}
if ((*Path[0]) == '\\')
{
end = wcschr((*Path) + 1, '\\');
if (end != NULL)
*end = 0;
wcstombs(cPath, (*Path) + 1, wcslen((*Path) + 1));
cPath[wcslen((*Path) + 1)] = 0;
}
else
{
end = wcschr((*Path), '\\');
if (end != NULL)
*end = 0;
wcstombs(cPath, (*Path), wcslen((*Path)));
cPath[wcslen((*Path))] = 0;
}
FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes);
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
cPath,
0,
Attributes);
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
{
if (end != NULL)
{
*end = '\\';
}
return STATUS_UNSUCCESSFUL;
}
/* Create new key object and put into linked list */
DPRINT("CmiObjectParse %s\n", cPath);
Status = ObCreateObject(NULL,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiKeyType,
(PVOID*) &FoundObject);
if (!NT_SUCCESS(Status))
{
return Status;
}
FoundObject->Flags = 0;
FoundObject->Name = SubKeyCell->Name;
FoundObject->NameSize = SubKeyCell->NameSize;
FoundObject->KeyCell = SubKeyCell;
FoundObject->BlockOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%x\n", FoundObject);
}
else
{ {
ObReferenceObjectByPointer(FoundObject, DPRINT("*Path is NULL\n");
STANDARD_RIGHTS_REQUIRED, return STATUS_UNSUCCESSFUL;
NULL,
UserMode);
} }
DPRINT("CmiObjectParse %s\n", FoundObject->Name); DPRINT("Path '%S'\n", *Path);
if (end != NULL) if ((*Path[0]) == '\\')
{ {
*end = '\\'; end = wcschr((*Path) + 1, '\\');
*Path = end; if (end != NULL)
} *end = 0;
wcstombs(cPath, (*Path) + 1, wcslen((*Path) + 1));
cPath[wcslen((*Path) + 1)] = 0;
}
else else
{
end = wcschr((*Path), '\\');
if (end != NULL)
*end = 0;
wcstombs(cPath, (*Path), wcslen((*Path)));
cPath[wcslen((*Path))] = 0;
}
FoundObject = CmiScanKeyList(ParsedKey, cPath, Attributes);
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryHive,
ParsedKey->KeyCell,
&SubKeyCell,
&BlockOffset,
cPath,
0,
Attributes);
if (!NT_SUCCESS(Status) || (SubKeyCell == NULL))
{
if (end != NULL)
{
*end = '\\';
}
return(STATUS_UNSUCCESSFUL);
}
if ((SubKeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
!((Attributes & OBJ_OPENLINK) && (end == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(ParsedKey->RegistryHive,
SubKeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
DPRINT("LinkPath '%wZ'\n", &LinkPath);
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (end != NULL)
{ {
*Path = NULL; *end = '\\';
TargetPath.MaximumLength += (wcslen(end) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (end != NULL)
{
wcscat(TargetPath.Buffer, end);
} }
VERIFY_KEY_OBJECT(FoundObject); RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
*NextObject = FoundObject; DPRINT("FullPath '%wZ'\n", FullPath);
return STATUS_SUCCESS; /* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
*NextObject = NULL;
return(STATUS_REPARSE);
}
}
/* Create new key object and put into linked list */
DPRINT("CmiObjectParse %s\n", cPath);
Status = ObCreateObject(NULL,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiKeyType,
(PVOID*)&FoundObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
FoundObject->Flags = 0;
FoundObject->Name = SubKeyCell->Name;
FoundObject->NameSize = SubKeyCell->NameSize;
FoundObject->KeyCell = SubKeyCell;
FoundObject->BlockOffset = BlockOffset;
FoundObject->RegistryHive = ParsedKey->RegistryHive;
CmiAddKeyToList(ParsedKey, FoundObject);
DPRINT("Created object 0x%x\n", FoundObject);
}
else
{
if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
!((Attributes & OBJ_OPENLINK) && (end == NULL)))
{
RtlInitUnicodeString(&LinkPath, NULL);
Status = CmiGetLinkTarget(FoundObject->RegistryHive,
FoundObject->KeyCell,
&LinkPath);
if (NT_SUCCESS(Status))
{
DPRINT("LinkPath '%wZ'\n", &LinkPath);
/* build new FullPath for reparsing */
TargetPath.MaximumLength = LinkPath.MaximumLength;
if (end != NULL)
{
*end = '\\';
TargetPath.MaximumLength += (wcslen(end) * sizeof(WCHAR));
}
TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR);
TargetPath.Buffer = ExAllocatePool(NonPagedPool,
TargetPath.MaximumLength);
wcscpy(TargetPath.Buffer, LinkPath.Buffer);
if (end != NULL)
{
wcscat(TargetPath.Buffer, end);
}
RtlFreeUnicodeString(FullPath);
RtlFreeUnicodeString(&LinkPath);
FullPath->Length = TargetPath.Length;
FullPath->MaximumLength = TargetPath.MaximumLength;
FullPath->Buffer = TargetPath.Buffer;
DPRINT("FullPath '%wZ'\n", FullPath);
/* reinitialize Path for reparsing */
*Path = FullPath->Buffer;
*NextObject = NULL;
return(STATUS_REPARSE);
}
}
ObReferenceObjectByPointer(FoundObject,
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
}
DPRINT("CmiObjectParse %s\n", FoundObject->Name);
if (end != NULL)
{
*end = '\\';
*Path = end;
}
else
{
*Path = NULL;
}
VERIFY_KEY_OBJECT(FoundObject);
*NextObject = FoundObject;
return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectCreate(PVOID ObjectBody, CmiObjectCreate(PVOID ObjectBody,
PVOID Parent, PVOID Parent,
PWSTR RemainingPath, PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes) struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{ {
PKEY_OBJECT pKey = ObjectBody; PKEY_OBJECT pKey = ObjectBody;
pKey->ParentKey = Parent;
if (RemainingPath) pKey->ParentKey = Parent;
{ if (RemainingPath)
if(RemainingPath[0]== L'\\') {
{ if(RemainingPath[0]== L'\\')
pKey->Name = (PCHAR) (&RemainingPath[1]); {
pKey->NameSize = wcslen(RemainingPath) - 1; pKey->Name = (PCHAR)(&RemainingPath[1]);
} pKey->NameSize = wcslen(RemainingPath) - 1;
else }
{ else
pKey->Name = (PCHAR) RemainingPath; {
pKey->NameSize = wcslen(RemainingPath); pKey->Name = (PCHAR)RemainingPath;
} pKey->NameSize = wcslen(RemainingPath);
} }
}
else else
{ {
pKey->NameSize = 0; pKey->NameSize = 0;
@ -177,16 +272,16 @@ CmiObjectDelete(PVOID DeletedObject)
KeyObject = (PKEY_OBJECT) DeletedObject; KeyObject = (PKEY_OBJECT) DeletedObject;
if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject))) if (!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
{ {
DPRINT1("Key not found in parent list ???\n"); DPRINT1("Key not found in parent list ???\n");
} }
if (KeyObject->Flags & KO_MARKED_FOR_DELETE) if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
{ {
DPRINT("delete really key\n"); DPRINT("delete really key\n");
CmiDestroyBlock(KeyObject->RegistryHive, CmiDestroyBlock(KeyObject->RegistryHive,
KeyObject->KeyCell, KeyObject->KeyCell,
KeyObject->BlockOffset); KeyObject->BlockOffset);
} }
else else
{ {
@ -194,9 +289,10 @@ CmiObjectDelete(PVOID DeletedObject)
} }
} }
VOID VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey, CmiAddKeyToList(PKEY_OBJECT ParentKey,
PKEY_OBJECT NewKey) PKEY_OBJECT NewKey)
{ {
KIRQL OldIrql; KIRQL OldIrql;
@ -205,29 +301,29 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys) if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
{ {
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool, PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
(ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD)); (ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
if (ParentKey->NumberOfSubKeys > 0) if (ParentKey->NumberOfSubKeys > 0)
{ {
memcpy(tmpSubKeys, memcpy(tmpSubKeys,
ParentKey->SubKeys, ParentKey->SubKeys,
ParentKey->NumberOfSubKeys * sizeof(DWORD)); ParentKey->NumberOfSubKeys * sizeof(DWORD));
} }
if (ParentKey->SubKeys) if (ParentKey->SubKeys)
ExFreePool(ParentKey->SubKeys); ExFreePool(ParentKey->SubKeys);
ParentKey->SubKeys = tmpSubKeys; ParentKey->SubKeys = tmpSubKeys;
ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys + 1; ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys + 1;
} }
/* FIXME: Please maintain the list in alphabetic order */ /* FIXME: Please maintain the list in alphabetic order */
/* to allow a dichotomic search */ /* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->NumberOfSubKeys++] = NewKey; ParentKey->SubKeys[ParentKey->NumberOfSubKeys++] = NewKey;
DPRINT("Reference parent key: 0x%x\n", ParentKey); DPRINT("Reference parent key: 0x%x\n", ParentKey);
ObReferenceObjectByPointer(ParentKey, ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED, STANDARD_RIGHTS_REQUIRED,
@ -249,36 +345,37 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: If list maintained in alphabetic order, use dichotomic search */ /* FIXME: If list maintained in alphabetic order, use dichotomic search */
for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++) for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++)
{ {
if (ParentKey->SubKeys[Index] == KeyToRemove) if (ParentKey->SubKeys[Index] == KeyToRemove)
{ {
if (Index < ParentKey->NumberOfSubKeys-1) if (Index < ParentKey->NumberOfSubKeys-1)
RtlMoveMemory(&ParentKey->SubKeys[Index], RtlMoveMemory(&ParentKey->SubKeys[Index],
&ParentKey->SubKeys[Index + 1], &ParentKey->SubKeys[Index + 1],
(ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT)); (ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
ParentKey->NumberOfSubKeys--; ParentKey->NumberOfSubKeys--;
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
DPRINT("Dereference parent key: 0x%x\n", ParentKey); DPRINT("Dereference parent key: 0x%x\n", ParentKey);
ObDereferenceObject(ParentKey); ObDereferenceObject(ParentKey);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
PKEY_OBJECT PKEY_OBJECT
CmiScanKeyList(PKEY_OBJECT Parent, CmiScanKeyList(PKEY_OBJECT Parent,
PCHAR KeyName, PCHAR KeyName,
ULONG Attributes) ULONG Attributes)
{ {
PKEY_OBJECT CurKey; PKEY_OBJECT CurKey;
KIRQL OldIrql; KIRQL OldIrql;
WORD NameSize; WORD NameSize;
DWORD Index; DWORD Index;
DPRINT("Scanning key list for %s (Parent %s)\n", DPRINT("Scanning key list for %s (Parent %s)\n",
KeyName, Parent->Name); KeyName, Parent->Name);
@ -287,28 +384,88 @@ CmiScanKeyList(PKEY_OBJECT Parent,
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql); KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */ /* FIXME: if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->NumberOfSubKeys; Index++) for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
{ {
CurKey = Parent->SubKeys[Index]; CurKey = Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE) if (Attributes & OBJ_CASE_INSENSITIVE)
{ {
if ((NameSize == CurKey->NameSize) if ((NameSize == CurKey->NameSize)
&& (_strnicmp(KeyName, CurKey->Name, NameSize) == 0)) && (_strnicmp(KeyName, CurKey->Name, NameSize) == 0))
{ {
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey; return CurKey;
} }
} }
else else
{ {
if ((NameSize == CurKey->NameSize) if ((NameSize == CurKey->NameSize)
&& (strncmp(KeyName,CurKey->Name,NameSize) == 0)) && (strncmp(KeyName,CurKey->Name,NameSize) == 0))
{ {
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey; return CurKey;
} }
} }
} }
KeReleaseSpinLock(&CmiKeyListLock, OldIrql); KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return NULL; return NULL;
} }
static NTSTATUS
CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell,
PUNICODE_STRING TargetPath)
{
PVALUE_CELL ValueCell;
PDATA_CELL DataCell;
NTSTATUS Status;
/* Get Value block of interest */
Status = CmiScanKeyForValue(RegistryHive,
KeyCell,
"SymbolicLinkValue",
&ValueCell,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ValueCell->DataType != REG_LINK)
{
DPRINT1("Type != REG_LINK\n!");
return(STATUS_UNSUCCESSFUL);
}
if (TargetPath->Buffer == NULL && TargetPath->MaximumLength == 0)
{
TargetPath->Length = 0;
TargetPath->MaximumLength = ValueCell->DataSize + sizeof(WCHAR);
TargetPath->Buffer = ExAllocatePool(NonPagedPool,
TargetPath->MaximumLength);
}
TargetPath->Length = min(TargetPath->MaximumLength - sizeof(WCHAR),
ValueCell->DataSize);
if (ValueCell->DataSize > 0)
{
DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
RtlCopyMemory(TargetPath->Buffer,
DataCell->Data,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
CmiReleaseBlock(RegistryHive, DataCell);
}
else
{
RtlCopyMemory(TargetPath->Buffer,
&ValueCell->DataOffset,
TargetPath->Length);
TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
}
return(STATUS_SUCCESS);
}
/* EOF */

View file

@ -2,13 +2,13 @@ REGEDIT4
[\Registry\Machine\SYSTEM] [\Registry\Machine\SYSTEM]
[\Registry\Machine\SYSTEM\CurrentControlSet] [\Registry\Machine\SYSTEM\ControlSet001]
[\Registry\Machine\SYSTEM\CurrentControlSet\Control] [\Registry\Machine\SYSTEM\ControlSet001\Control]
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\NLS] [\Registry\Machine\SYSTEM\ControlSet001\Control\NLS]
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\NLS\CodePage] [\Registry\Machine\SYSTEM\ControlSet001\Control\NLS\CodePage]
"10000"="c_10000.nls" "10000"="c_10000.nls"
"1252"="c_1252.nls" "1252"="c_1252.nls"
"437"="c_437.nls" "437"="c_437.nls"
@ -17,7 +17,7 @@ REGEDIT4
"OEMCP"="437" "OEMCP"="437"
"MACCP"="10000" "MACCP"="10000"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\NLS\Language] [\Registry\Machine\SYSTEM\ControlSet001\Control\NLS\Language]
"0401"="l_intl.nls" "0401"="l_intl.nls"
"0402"="l_intl.nls" "0402"="l_intl.nls"
"0403"="l_intl.nls" "0403"="l_intl.nls"
@ -37,18 +37,18 @@ REGEDIT4
"Default"="0409" "Default"="0409"
"InstallLanguage"="0409" "InstallLanguage"="0409"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder] [\Registry\Machine\SYSTEM\ControlSet001\Control\ServiceGroupOrder]
"List"=multi:"SCSI Port", "SCSI Miniport", "Primary Disk", "SCSI Class Helper", \ "List"=multi:"SCSI Port", "SCSI Miniport", "Primary Disk", "SCSI Class Helper", \
"SCSI Class", "Boot File System", "Base", "Pointer Port", \ "SCSI Class", "Boot File System", "Base", "Pointer Port", \
"Keyboard Port", "Pointer Class", "Keyboard Class", "Debug", \ "Keyboard Port", "Pointer Class", "Keyboard Class", "Debug", \
"Video Init", "Video", "File System", "Event log", "NDIS", \ "Video Init", "Video", "File System", "Event log", "NDIS", \
"PNP_TDI", "TDI", "Extended Base" "PNP_TDI", "TDI", "Extended Base"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager] [\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager]
"BootExecute"=multi:"autocheck autochk *" "BootExecute"=multi:"autocheck autochk *"
"ObjectDirectories"=multi:"\Windows", "\RPC Control" "ObjectDirectories"=multi:"\Windows", "\RPC Control"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices] [\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager\DOS Devices]
"AUX"="\DosDevices\COM1" "AUX"="\DosDevices\COM1"
"MAILSLOT"="\Device\MailSlot" "MAILSLOT"="\Device\MailSlot"
"NUL"="\Device\Null" "NUL"="\Device\Null"
@ -56,187 +56,197 @@ REGEDIT4
"PRN"="\DosDevices\LPT1" "PRN"="\DosDevices\LPT1"
"UNC"="\Device\Mup" "UNC"="\Device\Mup"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager\Environment] [\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager\Environment]
"ComSpec"=expand:"%SystemRoot%\system32\shell.exe" "ComSpec"=expand:"%SystemRoot%\system32\shell.exe"
"OS"=expand:"ReactOS" "OS"=expand:"ReactOS"
"Path"=expand:"%SystemRoot%\system32;%SystemRoot%" "Path"=expand:"%SystemRoot%\system32;%SystemRoot%"
"windir"=expand:"%SystemRoot%" "windir"=expand:"%SystemRoot%"
[\Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management] [\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager\Memory Management]
"PagingFiles"=multi:"C:\reactos\pagefile.sys" "PagingFiles"=multi:"C:\reactos\pagefile.sys"
[\Registry\Machine\SYSTEM\CurrentControlSet\Services] [\Registry\Machine\SYSTEM\ControlSet001\Services]
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Afd] [\Registry\Machine\SYSTEM\ControlSet001\Services\Afd]
"ErrorControl"=dword:00000001 "ErrorControl"=dword:00000001
"Group"="TDI" "Group"="TDI"
"ImagePath"="system32\drivers\afd.sys" "ImagePath"=expand:"system32\drivers\afd.sys"
"Start"=dword:00000002 "Start"=dword:00000002
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Atapi] [\Registry\Machine\SYSTEM\ControlSet001\Services\Atapi]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="SCSI Miniport" "Group"="SCSI Miniport"
"ImagePath"="system32\drivers\atapi.sys" "ImagePath"=expand:"system32\drivers\atapi.sys"
"Start"=dword:00000000 "Start"=dword:00000000
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Beep] [\Registry\Machine\SYSTEM\ControlSet001\Services\Beep]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Base" "Group"="Base"
"ImagePath"="system32\drivers\beep.sys" "ImagePath"=expand:"system32\drivers\beep.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Blue] [\Registry\Machine\SYSTEM\ControlSet001\Services\Blue]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Video Init" "Group"="Video Init"
"ImagePath"="system32\drivers\blue.sys" "ImagePath"=expand:"system32\drivers\blue.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Cdfs] [\Registry\Machine\SYSTEM\ControlSet001\Services\Cdfs]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="File System" "Group"="File System"
"ImagePath"="system32\drivers\cdfs.sys" "ImagePath"=expand:"system32\drivers\cdfs.sys"
"Start"=dword:00000003 "Start"=dword:00000003
"Type"=dword:00000002 "Type"=dword:00000002
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Cdrom] [\Registry\Machine\SYSTEM\ControlSet001\Services\Cdrom]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="SCSI Class" "Group"="SCSI Class"
"ImagePath"="system32\drivers\cdrom.sys" "ImagePath"=expand:"system32\drivers\cdrom.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Class2] [\Registry\Machine\SYSTEM\ControlSet001\Services\Class2]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="SCSI Class Helper" "Group"="SCSI Class Helper"
"ImagePath"="system32\drivers\class2.sys" "ImagePath"=expand:"system32\drivers\class2.sys"
"Start"=dword:00000000 "Start"=dword:00000000
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Disk] [\Registry\Machine\SYSTEM\ControlSet001\Services\Disk]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="SCSI Class" "Group"="SCSI Class"
"ImagePath"="system32\drivers\disk.sys" "ImagePath"=expand:"system32\drivers\disk.sys"
"Start"=dword:00000000 "Start"=dword:00000000
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\EventLog] [\Registry\Machine\SYSTEM\ControlSet001\Services\EventLog]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Event log" "Group"="Event log"
"ImagePath"="%SystemRoot%\system32\eventlog.exe" "ImagePath"=expand:"%SystemRoot%\system32\eventlog.exe"
"Start"=dword:00000004 "Start"=dword:00000004
"Type"=dword:00000020 "Type"=dword:00000010
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Floppy] [\Registry\Machine\SYSTEM\ControlSet001\Services\Floppy]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Primary Disk" "Group"="Primary Disk"
"ImagePath"="system32\drivers\floppy.sys" "ImagePath"=expand:"system32\drivers\floppy.sys"
"Start"=dword:00000004 "Start"=dword:00000004
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Fs_Rec] [\Registry\Machine\SYSTEM\ControlSet001\Services\Fs_Rec]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Boot file system" "Group"="Boot file system"
"ImagePath"="system32\drivers\fs_rec.sys" "ImagePath"=expand:"system32\drivers\fs_rec.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000008 "Type"=dword:00000008
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ide] [\Registry\Machine\SYSTEM\ControlSet001\Services\Ide]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Primary Disk" "Group"="Primary Disk"
"ImagePath"="system32\drivers\ide.sys" "ImagePath"=expand:"system32\drivers\ide.sys"
"Start"=dword:00000004 "Start"=dword:00000004
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Keyboard] [\Registry\Machine\SYSTEM\ControlSet001\Services\Keyboard]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Keyboard Port" "Group"="Keyboard Port"
"ImagePath"="system32\drivers\keyboard.sys" "ImagePath"=expand:"system32\drivers\keyboard.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Msfs] [\Registry\Machine\SYSTEM\ControlSet001\Services\Msfs]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="File System" "Group"="File System"
"ImagePath"="system32\drivers\msfs.sys" "ImagePath"=expand:"system32\drivers\msfs.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000002 "Type"=dword:00000002
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ne2000] [\Registry\Machine\SYSTEM\ControlSet001\Services\Ne2000]
"ErrorControl"=dword:00000001 "ErrorControl"=dword:00000001
"Group"="NDIS" "Group"="NDIS"
"ImagePath"="system32\drivers\ne2000.sys" "ImagePath"=expand:"system32\drivers\ne2000.sys"
"Start"=dword:00000004 "Start"=dword:00000004
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ndis] [\Registry\Machine\SYSTEM\ControlSet001\Services\Ndis]
"ErrorControl"=dword:00000001 "ErrorControl"=dword:00000001
"Group"="NDIS" "Group"="NDIS"
"ImagePath"="system32\drivers\ndis.sys" "ImagePath"=expand:"system32\drivers\ndis.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Npfs] [\Registry\Machine\SYSTEM\ControlSet001\Services\Npfs]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="File System" "Group"="File System"
"ImagePath"="system32\drivers\npfs.sys" "ImagePath"=expand:"system32\drivers\npfs.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000002 "Type"=dword:00000002
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ntfs] [\Registry\Machine\SYSTEM\ControlSet001\Services\Ntfs]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="File System" "Group"="File System"
"ImagePath"="system32\drivers\ntfs.sys" "ImagePath"=expand:"system32\drivers\ntfs.sys"
"Start"=dword:00000003 "Start"=dword:00000003
"Type"=dword:00000002 "Type"=dword:00000002
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Null] [\Registry\Machine\SYSTEM\ControlSet001\Services\Null]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Base" "Group"="Base"
"ImagePath"="system32\drivers\null.sys" "ImagePath"=expand:"system32\drivers\null.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Pice] [\Registry\Machine\SYSTEM\ControlSet001\Services\Pice]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Debug" "Group"="Debug"
"ImagePath"="system32\drivers\pice.sys" "ImagePath"=expand:"system32\drivers\pice.sys"
"Start"=dword:00000004 "Start"=dword:00000004
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Scsiport] [\Registry\Machine\SYSTEM\ControlSet001\Services\RpcSs]
"ErrorControl"=dword:00000001
"ImagePath"=expand:"%SystemRoot%\system32\rpcss.exe"
"Start"=dword:00000004
"Type"=dword:00000010
[\Registry\Machine\SYSTEM\ControlSet001\Services\Scsiport]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="SCSI Port" "Group"="SCSI Port"
"ImagePath"="system32\drivers\scsiport.sys" "ImagePath"=expand:"system32\drivers\scsiport.sys"
"Start"=dword:00000000 "Start"=dword:00000000
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Tcpip] [\Registry\Machine\SYSTEM\ControlSet001\Services\Tcpip]
"ErrorControl"=dword:00000001 "ErrorControl"=dword:00000001
"Group"="PNP_TDI" "Group"="PNP_TDI"
"ImagePath"="system32\drivers\tcpip.sys" "ImagePath"=expand:"system32\drivers\tcpip.sys"
"Start"=dword:00000002 "Start"=dword:00000002
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Vfatfs] [\Registry\Machine\SYSTEM\ControlSet001\Services\Vfatfs]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Boot File System" "Group"="Boot File System"
"ImagePath"="system32\drivers\vfatfs.sys" "ImagePath"=expand:"system32\drivers\vfatfs.sys"
"Start"=dword:00000000 "Start"=dword:00000000
"Type"=dword:00000002 "Type"=dword:00000002
[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Vga] [\Registry\Machine\SYSTEM\ControlSet001\Services\Vga]
"ErrorControl"=dword:00000000 "ErrorControl"=dword:00000000
"Group"="Video" "Group"="Video"
"ImagePath"="system32\drivers\vgamp.sys" "ImagePath"=expand:"system32\drivers\vgamp.sys"
"Start"=dword:00000001 "Start"=dword:00000001
"Type"=dword:00000001 "Type"=dword:00000001
[\Registry\Machine\SYSTEM\ControlSet002]
[\Registry\Machine\SYSTEM\Select] [\Registry\Machine\SYSTEM\Select]
"Current"=dword:00000001 "Current"=dword:00000001
"Default"=dword:00000001 "Default"=dword:00000001
"Failed"=dword:00000000 "Failed"=dword:00000000
"LastKnownGood"=dword:00000000 "LastKnownGood"=dword:00000000
[\Registry\Machine\SYSTEM\Setup]