mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
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:
parent
5c4728ed0a
commit
79d575aef4
8 changed files with 683 additions and 405 deletions
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -13,151 +13,246 @@
|
|||
#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;
|
||||
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 */
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue