Create the 'CurrentControlSet' link after the registry has been initialized.
svn path=/trunk/; revision=3130
UCHAR Data[1];
} 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 */
-/* $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
* PROJECT: ReactOS kernel
#define __INCLUDE_NTOS_REGISTRY_H
/* Key access rights */
-#define KEY_QUERY_VALUE (1)
-#define KEY_SET_VALUE (2)
-#define KEY_CREATE_SUB_KEY (4)
-#define KEY_ENUMERATE_SUB_KEYS (8)
-#define KEY_NOTIFY (16)
-#define KEY_CREATE_LINK (32)
-
-#define KEY_READ (0x20019L)
-#define KEY_WRITE (0x20006L)
-#define KEY_EXECUTE (0x20019L)
-#define KEY_ALL_ACCESS (0xf003fL)
-
-
-/* RegCreateKeyEx */
-#define REG_OPTION_VOLATILE (0x1L)
-#define REG_OPTION_NON_VOLATILE (0L)
-#define REG_CREATED_NEW_KEY (0x1L)
-#define REG_OPENED_EXISTING_KEY (0x2L)
-
-
-/* RegEnumValue */
+#define KEY_QUERY_VALUE (1)
+#define KEY_SET_VALUE (2)
+#define KEY_CREATE_SUB_KEY (4)
+#define KEY_ENUMERATE_SUB_KEYS (8)
+#define KEY_NOTIFY (16)
+#define KEY_CREATE_LINK (32)
+
+#define KEY_READ (0x20019L)
+#define KEY_WRITE (0x20006L)
+#define KEY_EXECUTE (0x20019L)
+#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)
+
+/* Key create/open disposition */
+#define REG_CREATED_NEW_KEY (0x1L)
+#define REG_OPENED_EXISTING_KEY (0x2L)
+
+/* Value types */
#define REG_NONE (0)
#define REG_SZ (1)
#define REG_EXPAND_SZ (2)
#define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
#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 REG_MACHINE_STD_HANDLE_NAME "HKEY_LOCAL_MACHINE"
atempts to access the key must not succeed */
#define KO_MARKED_FOR_DELETE 0x00000001
+
/* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT
{
extern BOOLEAN CmiDoVerify;
+extern PREGISTRY_HIVE CmiVolatileHive;
+extern POBJECT_TYPE CmiKeyType;
+extern KSPIN_LOCK CmiKeyListLock;
VOID
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
- UNICODE_STRING RemainingPath;
- PKEY_OBJECT KeyObject;
- NTSTATUS Status;
- PVOID Object;
- PWSTR End;
+ UNICODE_STRING RemainingPath;
+ PKEY_OBJECT KeyObject;
+ NTSTATUS Status;
+ PVOID Object;
+ PWSTR End;
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
ObjectAttributes->ObjectName,
Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType);
if (!NT_SUCCESS(Status))
- {
- return Status;
+ {
+ return Status;
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0))
- {
- /* Fail if the key has been deleted */
- if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
- {
- ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
- }
+ {
+ /* Fail if the key has been deleted */
+ if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
+ {
+ ObDereferenceObject(Object);
+ return STATUS_UNSUCCESSFUL;
+ }
- if (Disposition)
- *Disposition = REG_OPENED_EXISTING_KEY;
+ if (Disposition)
+ *Disposition = REG_OPENED_EXISTING_KEY;
- Status = ObCreateHandle(PsGetCurrentProcess(),
- Object,
- DesiredAccess,
- FALSE,
- KeyHandle);
+ Status = ObCreateHandle(PsGetCurrentProcess(),
+ Object,
+ DesiredAccess,
+ FALSE,
+ KeyHandle);
- DPRINT("Status %x\n", Status);
- ObDereferenceObject(Object);
- return Status;
- }
+ DPRINT("Status %x\n", Status);
+ ObDereferenceObject(Object);
+ return Status;
+ }
/* If RemainingPath contains \ we must return error
because NtCreateKey don't create trees */
End = wcschr(RemainingPath.Buffer, '\\');
if (End != NULL)
- {
- ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
- }
+ {
+ ObDereferenceObject(Object);
+ return STATUS_UNSUCCESSFUL;
+ }
DPRINT("RemainingPath %S ParentObject %x\n", RemainingPath.Buffer, Object);
Status = ObCreateObject(KeyHandle,
- DesiredAccess,
- NULL,
- CmiKeyType,
- (PVOID*) &KeyObject);
+ DesiredAccess,
+ NULL,
+ CmiKeyType,
+ (PVOID*)&KeyObject);
if (!NT_SUCCESS(Status))
- return(Status);
+ return(Status);
KeyObject->ParentKey = Object;
// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql);
/* add key to subkeys of parent if needed */
Status = CmiAddSubKey(KeyObject->RegistryHive,
- KeyObject->ParentKey,
- KeyObject,
- RemainingPath.Buffer,
- RemainingPath.Length,
- TitleIndex,
- Class,
- CreateOptions);
+ KeyObject->ParentKey,
+ KeyObject,
+ RemainingPath.Buffer,
+ RemainingPath.Length,
+ TitleIndex,
+ Class,
+ CreateOptions);
if (!NT_SUCCESS(Status))
{
KeyObject->NameSize = KeyObject->KeyCell->NameSize;
if (KeyObject->RegistryHive == KeyObject->ParentKey->RegistryHive)
- {
- KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->BlockOffset;
- KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
- }
+ {
+ KeyObject->KeyCell->ParentKeyOffset = KeyObject->ParentKey->BlockOffset;
+ KeyObject->KeyCell->SecurityKeyOffset = KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
+ }
else
- {
- KeyObject->KeyCell->ParentKeyOffset = -1;
- KeyObject->KeyCell->SecurityKeyOffset = -1;
- /* This key must rest in memory unless it is deleted
- or file is unloaded */
- ObReferenceObjectByPointer(KeyObject,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- UserMode);
- }
+ {
+ KeyObject->KeyCell->ParentKeyOffset = -1;
+ KeyObject->KeyCell->SecurityKeyOffset = -1;
+ /* This key must rest in memory unless it is deleted
+ or file is unloaded */
+ ObReferenceObjectByPointer(KeyObject,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ UserMode);
+ }
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql);
NTSTATUS STDCALL
NtOpenKey(OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes)
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes)
{
- UNICODE_STRING RemainingPath;
- NTSTATUS Status;
- PVOID Object;
+ UNICODE_STRING RemainingPath;
+ NTSTATUS Status;
+ PVOID Object;
DPRINT("KH %x DA %x OA %x OA->ON %x\n",
- KeyHandle,
- DesiredAccess,
- ObjectAttributes,
- ObjectAttributes ? ObjectAttributes->ObjectName : NULL);
-
- RemainingPath.Buffer = NULL;
- Status = ObFindObject(ObjectAttributes,
- &Object,
- &RemainingPath,
- CmiKeyType);
-
+ KeyHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ObjectAttributes ? ObjectAttributes->ObjectName : NULL);
+
+ RemainingPath.Buffer = NULL;
+ Status = ObFindObject(ObjectAttributes,
+ &Object,
+ &RemainingPath,
+ CmiKeyType);
if (!NT_SUCCESS(Status))
- {
- return Status;
- }
+ {
+ return(Status);
+ }
VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
- DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
-
- if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
- {
- ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
- }
-
- /* Fail if the key has been deleted */
- if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE)
- {
- ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
- }
-
- Status = ObCreateHandle(
- PsGetCurrentProcess(),
- Object,
- DesiredAccess,
- FALSE,
- KeyHandle);
- ObDereferenceObject(Object);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- return STATUS_SUCCESS;
+ DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
+
+ if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
+ {
+ ObDereferenceObject(Object);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ /* Fail if the key has been deleted */
+ if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE)
+ {
+ ObDereferenceObject(Object);
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ Status = ObCreateHandle(PsGetCurrentProcess(),
+ Object,
+ DesiredAccess,
+ FALSE,
+ KeyHandle);
+ ObDereferenceObject(Object);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+ return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
-NtSetValueKey(
- IN HANDLE KeyHandle,
- IN PUNICODE_STRING ValueName,
- IN ULONG TitleIndex,
- IN ULONG Type,
- IN PVOID Data,
- IN ULONG DataSize)
+NtSetValueKey(IN HANDLE KeyHandle,
+ IN PUNICODE_STRING ValueName,
+ IN ULONG TitleIndex,
+ IN ULONG Type,
+ IN PVOID Data,
+ IN ULONG DataSize)
{
NTSTATUS Status;
PKEY_OBJECT KeyObject;
PDATA_CELL DataCell;
PDATA_CELL NewDataCell;
PHBIN pBin;
+ ULONG DesiredAccess;
// KIRQL OldIrql;
DPRINT("KeyHandle %x ValueName %S Type %d\n",
wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
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 */
Status = ObReferenceObjectByHandle(KeyHandle,
- KEY_SET_VALUE,
- CmiKeyType,
- UserMode,
- (PVOID *) &KeyObject,
- NULL);
+ DesiredAccess,
+ CmiKeyType,
+ UserMode,
+ (PVOID *)&KeyObject,
+ NULL);
if (!NT_SUCCESS(Status))
return(Status);
ValueCell->DataOffset = NewOffset;
}
+ if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
+ {
+ KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+ }
+
/* Update time of heap */
if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
{
#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;
&NKBOffset);
if (NewKeyCell == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
else
- {
+ {
NewKeyCell->Id = REG_KEY_CELL_ID;
NewKeyCell->Type = REG_KEY_CELL_TYPE;
ZwQuerySystemTime((PTIME) &NewKeyCell->LastWriteTime);
NTSTATUS
CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
- IN PKEY_CELL KeyCell,
- IN PCHAR ValueName)
+ IN PKEY_CELL KeyCell,
+ IN PCHAR ValueName)
{
PVALUE_LIST_CELL ValueListCell;
PVALUE_CELL CurValueCell;
- PHBIN pBin;
ULONG i;
ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
for (i = 0; i < KeyCell->NumberOfValues; i++)
{
- CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], &pBin);
+ CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
if ((CurValueCell != NULL) &&
(CurValueCell->NameSize == strlen(ValueName)) &&
(memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0))
KeyCell->NumberOfValues -= 1;
CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]);
- /* update time of heap */
- ZwQuerySystemTime((PTIME) &pBin->DateModified);
break;
}
CmiReleaseBlock(RegistryHive, CurValueCell);
HBOffset);
if ((NewHashBlock == NULL) || (!NT_SUCCESS(Status)))
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- }
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
else
- {
- NewHashBlock->Id = REG_HASH_TABLE_BLOCK_ID;
- NewHashBlock->HashTableSize = HashTableSize;
- *HashBlock = NewHashBlock;
- }
+ {
+ NewHashBlock->Id = REG_HASH_TABLE_BLOCK_ID;
+ NewHashBlock->HashTableSize = HashTableSize;
+ *HashBlock = NewHashBlock;
+ }
return Status;
}
BLOCK_OFFSET BlockOffset,
PHBIN * ppBin)
{
+ if (ppBin)
+ *ppBin = NULL;
+
if ((BlockOffset == 0) || (BlockOffset == -1))
return NULL;
-/* $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
* PROJECT: ReactOS kernel
CmiCheckKey(BOOLEAN Verbose,
HANDLE Key);
+static NTSTATUS
+CmiCreateCurrentControlSetLink(VOID);
+
+/* FUNCTIONS ****************************************************************/
VOID
CmiCheckSubKeys(BOOLEAN Verbose,
/* 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 */
PiceStart = 4;
}
+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
CmiConnectHive(PWSTR FileName,
PWSTR FullName,
#include <string.h>
#include <internal/pool.h>
#include <internal/registry.h>
+#include <ntos/minmax.h>
#define NDEBUG
#include <internal/debug.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
CmiObjectParse(PVOID ParsedObject,
- PVOID *NextObject,
- PUNICODE_STRING FullPath,
- PWSTR *Path,
- POBJECT_TYPE ObjectType,
- ULONG Attributes)
+ PVOID *NextObject,
+ PUNICODE_STRING FullPath,
+ PWSTR *Path,
+ POBJECT_TYPE ObjectType,
+ ULONG Attributes)
{
- BLOCK_OFFSET BlockOffset;
- PKEY_OBJECT FoundObject;
- PKEY_OBJECT ParsedKey;
- PKEY_CELL SubKeyCell;
- CHAR cPath[MAX_PATH];
- NTSTATUS Status;
- PWSTR end;
-
- ParsedKey = ParsedObject;
+ BLOCK_OFFSET BlockOffset;
+ PKEY_OBJECT FoundObject;
+ PKEY_OBJECT ParsedKey;
+ PKEY_CELL SubKeyCell;
+ CHAR cPath[MAX_PATH];
+ NTSTATUS Status;
+ PWSTR end;
+ UNICODE_STRING LinkPath;
+ UNICODE_STRING TargetPath;
+
+ ParsedKey = ParsedObject;
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;
- }
+ return STATUS_UNSUCCESSFUL;
+ }
- 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
+ DPRINT("Path '%S'\n", *Path);
+
+ if ((*Path[0]) == '\\')
{
- ObReferenceObjectByPointer(FoundObject,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- UserMode);
+ 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;
}
- DPRINT("CmiObjectParse %s\n", FoundObject->Name);
+ 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);
- if (end != NULL)
+ /* build new FullPath for reparsing */
+ TargetPath.MaximumLength = LinkPath.MaximumLength;
+ if (end != NULL)
{
- *end = '\\';
- *Path = end;
+ *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);
+ }
+ }
+
+ /* 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)
{
- *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);
-
- *NextObject = FoundObject;
-
- return STATUS_SUCCESS;
+ 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
CmiObjectCreate(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- struct _OBJECT_ATTRIBUTES* ObjectAttributes)
+ PVOID Parent,
+ PWSTR RemainingPath,
+ struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{
PKEY_OBJECT pKey = ObjectBody;
- pKey->ParentKey = Parent;
- if (RemainingPath)
- {
- if(RemainingPath[0]== L'\\')
- {
- pKey->Name = (PCHAR) (&RemainingPath[1]);
- pKey->NameSize = wcslen(RemainingPath) - 1;
- }
- else
- {
- pKey->Name = (PCHAR) RemainingPath;
- pKey->NameSize = wcslen(RemainingPath);
- }
- }
+
+ pKey->ParentKey = Parent;
+ if (RemainingPath)
+ {
+ if(RemainingPath[0]== L'\\')
+ {
+ pKey->Name = (PCHAR)(&RemainingPath[1]);
+ pKey->NameSize = wcslen(RemainingPath) - 1;
+ }
+ else
+ {
+ pKey->Name = (PCHAR)RemainingPath;
+ pKey->NameSize = wcslen(RemainingPath);
+ }
+ }
else
{
pKey->NameSize = 0;
KeyObject = (PKEY_OBJECT) DeletedObject;
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)
{
DPRINT("delete really key\n");
CmiDestroyBlock(KeyObject->RegistryHive,
- KeyObject->KeyCell,
- KeyObject->BlockOffset);
+ KeyObject->KeyCell,
+ KeyObject->BlockOffset);
}
else
{
}
}
+
VOID
CmiAddKeyToList(PKEY_OBJECT ParentKey,
- PKEY_OBJECT NewKey)
+ PKEY_OBJECT NewKey)
{
KIRQL OldIrql;
DPRINT("ParentKey %.08x\n", ParentKey);
-
+
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
- {
- PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
- (ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
+ {
+ PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
+ (ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
- if (ParentKey->NumberOfSubKeys > 0)
- {
- memcpy(tmpSubKeys,
- ParentKey->SubKeys,
- ParentKey->NumberOfSubKeys * sizeof(DWORD));
- }
+ if (ParentKey->NumberOfSubKeys > 0)
+ {
+ memcpy(tmpSubKeys,
+ ParentKey->SubKeys,
+ ParentKey->NumberOfSubKeys * sizeof(DWORD));
+ }
- if (ParentKey->SubKeys)
- ExFreePool(ParentKey->SubKeys);
+ if (ParentKey->SubKeys)
+ ExFreePool(ParentKey->SubKeys);
- ParentKey->SubKeys = tmpSubKeys;
- ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys + 1;
- }
+ ParentKey->SubKeys = tmpSubKeys;
+ ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys + 1;
+ }
/* FIXME: Please maintain the list in alphabetic order */
/* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->NumberOfSubKeys++] = NewKey;
-DPRINT("Reference parent key: 0x%x\n", ParentKey);
+ DPRINT("Reference parent key: 0x%x\n", ParentKey);
ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED,
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: If list maintained in alphabetic order, use dichotomic search */
for (Index = 0; Index < ParentKey->NumberOfSubKeys; Index++)
- {
- if (ParentKey->SubKeys[Index] == KeyToRemove)
- {
- if (Index < ParentKey->NumberOfSubKeys-1)
- RtlMoveMemory(&ParentKey->SubKeys[Index],
- &ParentKey->SubKeys[Index + 1],
- (ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
- ParentKey->NumberOfSubKeys--;
- KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
-
-DPRINT("Dereference parent key: 0x%x\n", ParentKey);
+ {
+ if (ParentKey->SubKeys[Index] == KeyToRemove)
+ {
+ if (Index < ParentKey->NumberOfSubKeys-1)
+ RtlMoveMemory(&ParentKey->SubKeys[Index],
+ &ParentKey->SubKeys[Index + 1],
+ (ParentKey->NumberOfSubKeys - Index - 1) * sizeof(PKEY_OBJECT));
+ ParentKey->NumberOfSubKeys--;
+ KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
+
+ DPRINT("Dereference parent key: 0x%x\n", ParentKey);
- ObDereferenceObject(ParentKey);
- return STATUS_SUCCESS;
- }
- }
+ ObDereferenceObject(ParentKey);
+ return STATUS_SUCCESS;
+ }
+ }
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
+
return STATUS_UNSUCCESSFUL;
}
PKEY_OBJECT
CmiScanKeyList(PKEY_OBJECT Parent,
- PCHAR KeyName,
- ULONG Attributes)
+ PCHAR KeyName,
+ ULONG Attributes)
{
- PKEY_OBJECT CurKey;
- KIRQL OldIrql;
- WORD NameSize;
- DWORD Index;
+ PKEY_OBJECT CurKey;
+ KIRQL OldIrql;
+ WORD NameSize;
+ DWORD Index;
DPRINT("Scanning key list for %s (Parent %s)\n",
KeyName, Parent->Name);
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
- {
- CurKey = Parent->SubKeys[Index];
- if (Attributes & OBJ_CASE_INSENSITIVE)
- {
- if ((NameSize == CurKey->NameSize)
- && (_strnicmp(KeyName, CurKey->Name, NameSize) == 0))
- {
- KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
- return CurKey;
- }
- }
- else
- {
- if ((NameSize == CurKey->NameSize)
- && (strncmp(KeyName,CurKey->Name,NameSize) == 0))
- {
- KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
- return CurKey;
- }
- }
- }
+ {
+ CurKey = Parent->SubKeys[Index];
+ if (Attributes & OBJ_CASE_INSENSITIVE)
+ {
+ if ((NameSize == CurKey->NameSize)
+ && (_strnicmp(KeyName, CurKey->Name, NameSize) == 0))
+ {
+ KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
+ return CurKey;
+ }
+ }
+ else
+ {
+ if ((NameSize == CurKey->NameSize)
+ && (strncmp(KeyName,CurKey->Name,NameSize) == 0))
+ {
+ KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
+ return CurKey;
+ }
+ }
+ }
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
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 */
[\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"
"1252"="c_1252.nls"
"437"="c_437.nls"
"OEMCP"="437"
"MACCP"="10000"
-[\Registry\Machine\SYSTEM\CurrentControlSet\Control\NLS\Language]
+[\Registry\Machine\SYSTEM\ControlSet001\Control\NLS\Language]
"0401"="l_intl.nls"
"0402"="l_intl.nls"
"0403"="l_intl.nls"
"Default"="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", \
"SCSI Class", "Boot File System", "Base", "Pointer Port", \
"Keyboard Port", "Pointer Class", "Keyboard Class", "Debug", \
"Video Init", "Video", "File System", "Event log", "NDIS", \
"PNP_TDI", "TDI", "Extended Base"
-[\Registry\Machine\SYSTEM\CurrentControlSet\Control\Session Manager]
+[\Registry\Machine\SYSTEM\ControlSet001\Control\Session Manager]
"BootExecute"=multi:"autocheck autochk *"
"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"
"MAILSLOT"="\Device\MailSlot"
"NUL"="\Device\Null"
"PRN"="\DosDevices\LPT1"
"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"
"OS"=expand:"ReactOS"
"Path"=expand:"%SystemRoot%\system32;%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"
-[\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
"Group"="TDI"
-"ImagePath"="system32\drivers\afd.sys"
+"ImagePath"=expand:"system32\drivers\afd.sys"
"Start"=dword:00000002
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Atapi]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Atapi]
"ErrorControl"=dword:00000000
"Group"="SCSI Miniport"
-"ImagePath"="system32\drivers\atapi.sys"
+"ImagePath"=expand:"system32\drivers\atapi.sys"
"Start"=dword:00000000
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Beep]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Beep]
"ErrorControl"=dword:00000000
"Group"="Base"
-"ImagePath"="system32\drivers\beep.sys"
+"ImagePath"=expand:"system32\drivers\beep.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Blue]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Blue]
"ErrorControl"=dword:00000000
"Group"="Video Init"
-"ImagePath"="system32\drivers\blue.sys"
+"ImagePath"=expand:"system32\drivers\blue.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Cdfs]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Cdfs]
"ErrorControl"=dword:00000000
"Group"="File System"
-"ImagePath"="system32\drivers\cdfs.sys"
+"ImagePath"=expand:"system32\drivers\cdfs.sys"
"Start"=dword:00000003
"Type"=dword:00000002
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Cdrom]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Cdrom]
"ErrorControl"=dword:00000000
"Group"="SCSI Class"
-"ImagePath"="system32\drivers\cdrom.sys"
+"ImagePath"=expand:"system32\drivers\cdrom.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Class2]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Class2]
"ErrorControl"=dword:00000000
"Group"="SCSI Class Helper"
-"ImagePath"="system32\drivers\class2.sys"
+"ImagePath"=expand:"system32\drivers\class2.sys"
"Start"=dword:00000000
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Disk]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Disk]
"ErrorControl"=dword:00000000
"Group"="SCSI Class"
-"ImagePath"="system32\drivers\disk.sys"
+"ImagePath"=expand:"system32\drivers\disk.sys"
"Start"=dword:00000000
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\EventLog]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\EventLog]
"ErrorControl"=dword:00000000
"Group"="Event log"
-"ImagePath"="%SystemRoot%\system32\eventlog.exe"
+"ImagePath"=expand:"%SystemRoot%\system32\eventlog.exe"
"Start"=dword:00000004
-"Type"=dword:00000020
+"Type"=dword:00000010
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Floppy]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Floppy]
"ErrorControl"=dword:00000000
"Group"="Primary Disk"
-"ImagePath"="system32\drivers\floppy.sys"
+"ImagePath"=expand:"system32\drivers\floppy.sys"
"Start"=dword:00000004
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Fs_Rec]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Fs_Rec]
"ErrorControl"=dword:00000000
"Group"="Boot file system"
-"ImagePath"="system32\drivers\fs_rec.sys"
+"ImagePath"=expand:"system32\drivers\fs_rec.sys"
"Start"=dword:00000001
"Type"=dword:00000008
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ide]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Ide]
"ErrorControl"=dword:00000000
"Group"="Primary Disk"
-"ImagePath"="system32\drivers\ide.sys"
+"ImagePath"=expand:"system32\drivers\ide.sys"
"Start"=dword:00000004
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Keyboard]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Keyboard]
"ErrorControl"=dword:00000000
"Group"="Keyboard Port"
-"ImagePath"="system32\drivers\keyboard.sys"
+"ImagePath"=expand:"system32\drivers\keyboard.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Msfs]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Msfs]
"ErrorControl"=dword:00000000
"Group"="File System"
-"ImagePath"="system32\drivers\msfs.sys"
+"ImagePath"=expand:"system32\drivers\msfs.sys"
"Start"=dword:00000001
"Type"=dword:00000002
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ne2000]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Ne2000]
"ErrorControl"=dword:00000001
"Group"="NDIS"
-"ImagePath"="system32\drivers\ne2000.sys"
+"ImagePath"=expand:"system32\drivers\ne2000.sys"
"Start"=dword:00000004
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ndis]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Ndis]
"ErrorControl"=dword:00000001
"Group"="NDIS"
-"ImagePath"="system32\drivers\ndis.sys"
+"ImagePath"=expand:"system32\drivers\ndis.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Npfs]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Npfs]
"ErrorControl"=dword:00000000
"Group"="File System"
-"ImagePath"="system32\drivers\npfs.sys"
+"ImagePath"=expand:"system32\drivers\npfs.sys"
"Start"=dword:00000001
"Type"=dword:00000002
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Ntfs]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Ntfs]
"ErrorControl"=dword:00000000
"Group"="File System"
-"ImagePath"="system32\drivers\ntfs.sys"
+"ImagePath"=expand:"system32\drivers\ntfs.sys"
"Start"=dword:00000003
"Type"=dword:00000002
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Null]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Null]
"ErrorControl"=dword:00000000
"Group"="Base"
-"ImagePath"="system32\drivers\null.sys"
+"ImagePath"=expand:"system32\drivers\null.sys"
"Start"=dword:00000001
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Pice]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Pice]
"ErrorControl"=dword:00000000
"Group"="Debug"
-"ImagePath"="system32\drivers\pice.sys"
+"ImagePath"=expand:"system32\drivers\pice.sys"
"Start"=dword:00000004
"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
"Group"="SCSI Port"
-"ImagePath"="system32\drivers\scsiport.sys"
+"ImagePath"=expand:"system32\drivers\scsiport.sys"
"Start"=dword:00000000
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Tcpip]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Tcpip]
"ErrorControl"=dword:00000001
"Group"="PNP_TDI"
-"ImagePath"="system32\drivers\tcpip.sys"
+"ImagePath"=expand:"system32\drivers\tcpip.sys"
"Start"=dword:00000002
"Type"=dword:00000001
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Vfatfs]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Vfatfs]
"ErrorControl"=dword:00000000
"Group"="Boot File System"
-"ImagePath"="system32\drivers\vfatfs.sys"
+"ImagePath"=expand:"system32\drivers\vfatfs.sys"
"Start"=dword:00000000
"Type"=dword:00000002
-[\Registry\Machine\SYSTEM\CurrentControlSet\Services\Vga]
+[\Registry\Machine\SYSTEM\ControlSet001\Services\Vga]
"ErrorControl"=dword:00000000
"Group"="Video"
-"ImagePath"="system32\drivers\vgamp.sys"
+"ImagePath"=expand:"system32\drivers\vgamp.sys"
"Start"=dword:00000001
"Type"=dword:00000001
+[\Registry\Machine\SYSTEM\ControlSet002]
+
[\Registry\Machine\SYSTEM\Select]
"Current"=dword:00000001
"Default"=dword:00000001
"Failed"=dword:00000000
"LastKnownGood"=dword:00000000
+
+[\Registry\Machine\SYSTEM\Setup]