diff --git a/reactos/include/ddk/cmtypes.h b/reactos/include/ddk/cmtypes.h index b44d83d8f92..a9af321f9c7 100644 --- a/reactos/include/ddk/cmtypes.h +++ b/reactos/include/ddk/cmtypes.h @@ -87,9 +87,6 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION 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 */ diff --git a/reactos/include/ntos/registry.h b/reactos/include/ntos/registry.h index 6282cc3b375..d2cf2f47046 100644 --- a/reactos/include/ntos/registry.h +++ b/reactos/include/ntos/registry.h @@ -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 * PROJECT: ReactOS kernel @@ -14,27 +14,30 @@ #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_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) +#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) -/* RegCreateKeyEx */ -#define REG_OPTION_VOLATILE (0x1L) -#define REG_OPTION_NON_VOLATILE (0L) -#define REG_CREATED_NEW_KEY (0x1L) -#define REG_OPENED_EXISTING_KEY (0x2L) +/* Key create/open disposition */ +#define REG_CREATED_NEW_KEY (0x1L) +#define REG_OPENED_EXISTING_KEY (0x2L) - -/* RegEnumValue */ +/* Value types */ #define REG_NONE (0) #define REG_SZ (1) #define REG_EXPAND_SZ (2) diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 6d9a2f2037f..0c208e61335 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -26,6 +26,21 @@ #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" @@ -247,6 +262,7 @@ typedef struct _REGISTRY_HIVE 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 { @@ -294,6 +310,9 @@ typedef struct _KEY_OBJECT extern BOOLEAN CmiDoVerify; +extern PREGISTRY_HIVE CmiVolatileHive; +extern POBJECT_TYPE CmiKeyType; +extern KSPIN_LOCK CmiKeyListLock; VOID diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index d709e776554..1a2ba4d44d7 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -32,11 +32,11 @@ NtCreateKey(OUT PHANDLE KeyHandle, 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, @@ -48,34 +48,34 @@ NtCreateKey(OUT PHANDLE KeyHandle, 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 */ @@ -85,21 +85,21 @@ NtCreateKey(OUT PHANDLE KeyHandle, 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; @@ -115,13 +115,13 @@ NtCreateKey(OUT PHANDLE KeyHandle, // 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)) { @@ -134,21 +134,21 @@ NtCreateKey(OUT PHANDLE KeyHandle, 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); @@ -807,61 +807,59 @@ END FIXME*/ 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); + DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer); - if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0)) - { - ObDereferenceObject(Object); - return STATUS_UNSUCCESSFUL; - } + 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); + /* Fail if the key has been deleted */ + if (((PKEY_OBJECT)Object)->Flags & KO_MARKED_FOR_DELETE) + { + ObDereferenceObject(Object); + return(STATUS_UNSUCCESSFUL); + } - if (!NT_SUCCESS(Status)) - { - return Status; - } - - return STATUS_SUCCESS; + Status = ObCreateHandle(PsGetCurrentProcess(), + Object, + DesiredAccess, + FALSE, + KeyHandle); + ObDereferenceObject(Object); + + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + return(STATUS_SUCCESS); } @@ -1185,13 +1183,12 @@ NtQueryValueKey(IN HANDLE KeyHandle, 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; @@ -1203,6 +1200,7 @@ NtSetValueKey( PDATA_CELL DataCell; PDATA_CELL NewDataCell; PHBIN pBin; + ULONG DesiredAccess; // KIRQL OldIrql; DPRINT("KeyHandle %x ValueName %S Type %d\n", @@ -1211,13 +1209,17 @@ NtSetValueKey( 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); @@ -1311,6 +1313,11 @@ NtSetValueKey( 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)) { diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index ebffb93bced..865011e4988 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -21,21 +21,6 @@ #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; @@ -1067,11 +1052,11 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive, &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); @@ -1339,12 +1324,11 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive, 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); @@ -1358,7 +1342,7 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, 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)) @@ -1376,8 +1360,6 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive, KeyCell->NumberOfValues -= 1; CmiDestroyValueCell(RegistryHive, CurValueCell, ValueListCell->Values[i]); - /* update time of heap */ - ZwQuerySystemTime((PTIME) &pBin->DateModified); break; } CmiReleaseBlock(RegistryHive, CurValueCell); @@ -1409,15 +1391,15 @@ CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive, 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; } @@ -1864,6 +1846,9 @@ CmiGetBlock(PREGISTRY_HIVE RegistryHive, BLOCK_OFFSET BlockOffset, PHBIN * ppBin) { + if (ppBin) + *ppBin = NULL; + if ((BlockOffset == 0) || (BlockOffset == -1)) return NULL; diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index 6df10380125..344001f450b 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -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 * PROJECT: ReactOS kernel @@ -42,6 +42,10 @@ VOID CmiCheckKey(BOOLEAN Verbose, HANDLE Key); +static NTSTATUS +CmiCreateCurrentControlSetLink(VOID); + +/* FUNCTIONS ****************************************************************/ VOID CmiCheckSubKeys(BOOLEAN Verbose, @@ -471,7 +475,9 @@ CmInit2(PCHAR CommandLine) /* 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; @@ -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 CmiConnectHive(PWSTR FileName, PWSTR FullName, diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index f1dc5efa9cd..e7b9c30ba2e 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -13,151 +13,246 @@ #include #include #include +#include #define NDEBUG #include #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; + 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; + ParsedKey = ParsedObject; VERIFY_KEY_OBJECT(ParsedKey); - *NextObject = NULL; + *NextObject = 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 + if ((*Path) == NULL) { - ObReferenceObjectByPointer(FoundObject, - STANDARD_RIGHTS_REQUIRED, - NULL, - UserMode); + DPRINT("*Path is NULL\n"); + return STATUS_UNSUCCESSFUL; } - DPRINT("CmiObjectParse %s\n", FoundObject->Name); + DPRINT("Path '%S'\n", *Path); - if (end != NULL) - { - *end = '\\'; - *Path = end; - } + 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); + } + + 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); - - *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); + } + } + + /* 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 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; @@ -177,16 +272,16 @@ CmiObjectDelete(PVOID DeletedObject) 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 { @@ -194,40 +289,41 @@ CmiObjectDelete(PVOID DeletedObject) } } + 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, @@ -249,36 +345,37 @@ CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove) 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); + { + 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); + 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); @@ -287,28 +384,88 @@ CmiScanKeyList(PKEY_OBJECT Parent, 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 */ diff --git a/reactos/system.hiv b/reactos/system.hiv index 634bbc77cc9..021c98ac434 100644 --- a/reactos/system.hiv +++ b/reactos/system.hiv @@ -2,13 +2,13 @@ REGEDIT4 [\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" @@ -17,7 +17,7 @@ REGEDIT4 "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" @@ -37,18 +37,18 @@ REGEDIT4 "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" @@ -56,187 +56,197 @@ REGEDIT4 "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]