mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 18:00:41 +00:00
Use ERESOURCE to lock registry hives.
Keep open hives in a global list. svn path=/trunk/; revision=3794
This commit is contained in:
parent
56b706f3e0
commit
a76689e99c
5 changed files with 527 additions and 262 deletions
|
@ -26,6 +26,12 @@
|
||||||
#define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
|
#define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
|
||||||
#define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY"
|
#define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY"
|
||||||
|
|
||||||
|
#define REG_SYSTEM_FILE_NAME L"\\SYSTEM"
|
||||||
|
#define REG_SOFTWARE_FILE_NAME L"\\SOFTWARE"
|
||||||
|
#define REG_USER_FILE_NAME L"\\DEFAULT"
|
||||||
|
#define REG_SAM_FILE_NAME L"\\SAM"
|
||||||
|
#define REG_SEC_FILE_NAME L"\\SECURITY"
|
||||||
|
|
||||||
#define REG_BLOCK_SIZE 4096
|
#define REG_BLOCK_SIZE 4096
|
||||||
#define REG_HBIN_DATA_OFFSET 32
|
#define REG_HBIN_DATA_OFFSET 32
|
||||||
#define REG_BIN_ID 0x6e696268
|
#define REG_BIN_ID 0x6e696268
|
||||||
|
@ -228,6 +234,7 @@ typedef struct _DATA_CELL
|
||||||
|
|
||||||
typedef struct _REGISTRY_HIVE
|
typedef struct _REGISTRY_HIVE
|
||||||
{
|
{
|
||||||
|
LIST_ENTRY HiveList;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
UNICODE_STRING Filename;
|
UNICODE_STRING Filename;
|
||||||
ULONG FileSize;
|
ULONG FileSize;
|
||||||
|
@ -240,8 +247,8 @@ typedef struct _REGISTRY_HIVE
|
||||||
ULONG FreeListMax;
|
ULONG FreeListMax;
|
||||||
PCELL_HEADER *FreeList;
|
PCELL_HEADER *FreeList;
|
||||||
BLOCK_OFFSET *FreeListOffset;
|
BLOCK_OFFSET *FreeListOffset;
|
||||||
// KSPIN_LOCK RegLock;
|
ERESOURCE HiveResource;
|
||||||
KSEMAPHORE RegSem;
|
|
||||||
// NTSTATUS (*Extend)(ULONG NewSize);
|
// NTSTATUS (*Extend)(ULONG NewSize);
|
||||||
// PVOID (*Flush)(VOID);
|
// PVOID (*Flush)(VOID);
|
||||||
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
} REGISTRY_HIVE, *PREGISTRY_HIVE;
|
||||||
|
@ -314,6 +321,9 @@ extern PREGISTRY_HIVE CmiVolatileHive;
|
||||||
extern POBJECT_TYPE CmiKeyType;
|
extern POBJECT_TYPE CmiKeyType;
|
||||||
extern KSPIN_LOCK CmiKeyListLock;
|
extern KSPIN_LOCK CmiKeyListLock;
|
||||||
|
|
||||||
|
extern LIST_ENTRY CmiHiveListHead;
|
||||||
|
extern KSPIN_LOCK CmiHiveListLock;
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CmiVerifyBinCell(PHBIN BinCell);
|
CmiVerifyBinCell(PHBIN BinCell);
|
||||||
|
@ -376,6 +386,9 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
PREGISTRY_HIVE *RegistryHive,
|
PREGISTRY_HIVE *RegistryHive,
|
||||||
BOOLEAN CreateNew);
|
BOOLEAN CreateNew);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
|
||||||
IN PKEY_CELL KeyCell);
|
IN PKEY_CELL KeyCell);
|
||||||
|
|
|
@ -58,11 +58,13 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
|
|
||||||
/* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
|
/* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
|
||||||
|
|
||||||
Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType);
|
Status = ObFindObject(ObjectAttributes,
|
||||||
|
&Object,
|
||||||
|
&RemainingPath,
|
||||||
|
CmiKeyType);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("RemainingPath %wZ\n", &RemainingPath);
|
DPRINT("RemainingPath %wZ\n", &RemainingPath);
|
||||||
|
@ -73,7 +75,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
|
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Disposition)
|
if (Disposition)
|
||||||
|
@ -112,7 +114,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
(PVOID*)&KeyObject);
|
(PVOID*)&KeyObject);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
return(Status);
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
KeyObject->ParentKey = Object;
|
KeyObject->ParentKey = Object;
|
||||||
|
|
||||||
|
@ -125,7 +129,10 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
KeyObject->NumberOfSubKeys = 0;
|
KeyObject->NumberOfSubKeys = 0;
|
||||||
KeyObject->SizeOfSubKeys = 0;
|
KeyObject->SizeOfSubKeys = 0;
|
||||||
KeyObject->SubKeys = NULL;
|
KeyObject->SubKeys = NULL;
|
||||||
// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql);
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
/* add key to subkeys of parent if needed */
|
/* add key to subkeys of parent if needed */
|
||||||
Status = CmiAddSubKey(KeyObject->RegistryHive,
|
Status = CmiAddSubKey(KeyObject->RegistryHive,
|
||||||
KeyObject->ParentKey,
|
KeyObject->ParentKey,
|
||||||
|
@ -138,6 +145,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
@ -164,7 +172,9 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
||||||
// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql);
|
|
||||||
|
/* Release hive lock */
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
|
@ -199,6 +209,9 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Set the marked for delete bit in the key object */
|
/* Set the marked for delete bit in the key object */
|
||||||
|
@ -213,6 +226,9 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
/* FIXME: I think that ObDeleteHandle should dereference the object */
|
/* FIXME: I think that ObDeleteHandle should dereference the object */
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
|
/* Release hive lock */
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,9 +271,12 @@ NtEnumerateKey(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
|
@ -269,9 +288,10 @@ NtEnumerateKey(
|
||||||
{
|
{
|
||||||
if (RegistryHive == CmiVolatileHive)
|
if (RegistryHive == CmiVolatileHive)
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
DPRINT("No more volatile entries\n");
|
DPRINT("No more volatile entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -290,9 +310,10 @@ NtEnumerateKey(
|
||||||
}
|
}
|
||||||
if (Index >= KeyCell->NumberOfSubKeys)
|
if (Index >= KeyCell->NumberOfSubKeys)
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
DPRINT("No more non-volatile entries\n");
|
DPRINT("No more non-volatile entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
}
|
}
|
||||||
SubKeyCell = CurKey->KeyCell;
|
SubKeyCell = CurKey->KeyCell;
|
||||||
}
|
}
|
||||||
|
@ -307,9 +328,10 @@ NtEnumerateKey(
|
||||||
|
|
||||||
if (SubKeyCell == NULL)
|
if (SubKeyCell == NULL)
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
DPRINT("No more entries\n");
|
DPRINT("No more entries\n");
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return(STATUS_NO_MORE_ENTRIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -417,11 +439,13 @@ NtEnumerateKey(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CmiReleaseBlock(RegistryHive, SubKeyCell);
|
CmiReleaseBlock(RegistryHive, SubKeyCell);
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
DPRINT("Returning status %x\n", Status);
|
DPRINT("Returning status %x\n", Status);
|
||||||
|
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,6 +488,9 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
|
@ -478,10 +505,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
else if (ValueCell != NULL)
|
|
||||||
|
if (ValueCell != NULL)
|
||||||
{
|
{
|
||||||
switch (KeyValueInformationClass)
|
switch (KeyValueInformationClass)
|
||||||
{
|
{
|
||||||
|
@ -588,6 +617,8 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
|
||||||
{
|
{
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -605,7 +636,6 @@ NtFlushKey(IN HANDLE KeyHandle)
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
// HANDLE FileHandleLog;
|
// HANDLE FileHandleLog;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
// KIRQL OldIrql;
|
|
||||||
LARGE_INTEGER fileOffset;
|
LARGE_INTEGER fileOffset;
|
||||||
DWORD * pEntDword;
|
DWORD * pEntDword;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
@ -625,10 +655,13 @@ NtFlushKey(IN HANDLE KeyHandle)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
RegistryHive = KeyObject->RegistryHive;
|
RegistryHive = KeyObject->RegistryHive;
|
||||||
// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
|
|
||||||
/* Then write changed blocks in .log */
|
/* Then write changed blocks in .log */
|
||||||
wcscpy(LogName,RegistryHive->Filename.Buffer);
|
wcscpy(LogName,RegistryHive->Filename.Buffer);
|
||||||
wcscat(LogName,L".log");
|
wcscat(LogName,L".log");
|
||||||
|
@ -721,9 +754,9 @@ END FIXME*/
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -739,10 +772,10 @@ END FIXME*/
|
||||||
sizeof(HIVE_HEADER),
|
sizeof(HIVE_HEADER),
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -756,9 +789,7 @@ END FIXME*/
|
||||||
|| (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
|
|| (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
|
||||||
== RegistryHive->HiveHeader->DateModified.dwHighDateTime
|
== RegistryHive->HiveHeader->DateModified.dwHighDateTime
|
||||||
&& RegistryHive->BlockList[i]->DateModified.dwLowDateTime
|
&& RegistryHive->BlockList[i]->DateModified.dwLowDateTime
|
||||||
> RegistryHive->HiveHeader->DateModified.dwLowDateTime
|
> RegistryHive->HiveHeader->DateModified.dwLowDateTime))
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
|
fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
|
||||||
Status = NtWriteFile(FileHandle,
|
Status = NtWriteFile(FileHandle,
|
||||||
|
@ -770,12 +801,12 @@ END FIXME*/
|
||||||
RegistryHive->BlockList[i]->BlockSize,
|
RegistryHive->BlockList[i]->BlockSize,
|
||||||
&fileOffset,
|
&fileOffset,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -807,12 +838,13 @@ END FIXME*/
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -906,12 +938,14 @@ NtQueryKey(IN HANDLE KeyHandle,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID *) &KeyObject,
|
(PVOID *) &KeyObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
|
@ -1023,11 +1057,13 @@ NtQueryKey(IN HANDLE KeyHandle,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
NtQueryValueKey(IN HANDLE KeyHandle,
|
NtQueryValueKey(IN HANDLE KeyHandle,
|
||||||
IN PUNICODE_STRING ValueName,
|
IN PUNICODE_STRING ValueName,
|
||||||
|
@ -1067,22 +1103,27 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
KeyCell = KeyObject->KeyCell;
|
KeyCell = KeyObject->KeyCell;
|
||||||
RegistryHive = KeyObject->RegistryHive;
|
RegistryHive = KeyObject->RegistryHive;
|
||||||
|
|
||||||
/* Get Value block of interest */
|
/* Get Value block of interest */
|
||||||
Status = CmiScanKeyForValue(RegistryHive,
|
Status = CmiScanKeyForValue(RegistryHive,
|
||||||
KeyCell,
|
KeyCell,
|
||||||
ValueName2,
|
ValueName2,
|
||||||
&ValueCell,NULL);
|
&ValueCell,
|
||||||
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
|
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
else if (ValueCell != NULL)
|
else if (ValueCell != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1189,6 +1230,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
|
||||||
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
Status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1214,7 +1256,6 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
PDATA_CELL NewDataCell;
|
PDATA_CELL NewDataCell;
|
||||||
PHBIN pBin;
|
PHBIN pBin;
|
||||||
ULONG DesiredAccess;
|
ULONG DesiredAccess;
|
||||||
// KIRQL OldIrql;
|
|
||||||
|
|
||||||
DPRINT("KeyHandle %x ValueName %S Type %d\n",
|
DPRINT("KeyHandle %x ValueName %S Type %d\n",
|
||||||
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
|
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
|
||||||
|
@ -1236,6 +1277,9 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return(Status);
|
return(Status);
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to key cell */
|
/* Get pointer to key cell */
|
||||||
|
@ -1250,12 +1294,11 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
{
|
{
|
||||||
DPRINT1("Value not found. Status 0x%X\n", Status);
|
DPRINT1("Value not found. Status 0x%X\n", Status);
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
|
|
||||||
|
|
||||||
if (ValueCell == NULL)
|
if (ValueCell == NULL)
|
||||||
{
|
{
|
||||||
Status = CmiAddValueToKey(RegistryHive,
|
Status = CmiAddValueToKey(RegistryHive,
|
||||||
|
@ -1269,6 +1312,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
{
|
{
|
||||||
DPRINT1("Cannot add value. Status 0x%X\n", Status);
|
DPRINT1("Cannot add value. Status 0x%X\n", Status);
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
@ -1338,8 +1382,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
DPRINT("Return Status 0x%X\n", Status);
|
DPRINT("Return Status 0x%X\n", Status);
|
||||||
|
@ -1352,12 +1395,9 @@ NTSTATUS STDCALL
|
||||||
NtDeleteValueKey(IN HANDLE KeyHandle,
|
NtDeleteValueKey(IN HANDLE KeyHandle,
|
||||||
IN PUNICODE_STRING ValueName)
|
IN PUNICODE_STRING ValueName)
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE RegistryHive;
|
|
||||||
CHAR ValueName2[MAX_PATH];
|
CHAR ValueName2[MAX_PATH];
|
||||||
PKEY_OBJECT KeyObject;
|
PKEY_OBJECT KeyObject;
|
||||||
PKEY_CELL KeyCell;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
// KIRQL OldIrql;
|
|
||||||
|
|
||||||
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
|
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
|
||||||
ValueName2[ValueName->Length>>1] = 0;
|
ValueName2[ValueName->Length>>1] = 0;
|
||||||
|
@ -1369,20 +1409,23 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID *)&KeyObject,
|
(PVOID *)&KeyObject,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
|
||||||
KeyCell = KeyObject->KeyCell;
|
KeyObject->KeyCell,
|
||||||
RegistryHive = KeyObject->RegistryHive;
|
ValueName2);
|
||||||
// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
|
|
||||||
Status = CmiDeleteValueFromKey(RegistryHive, KeyCell, ValueName2);
|
/* Release hive lock */
|
||||||
// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -1455,6 +1498,9 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acquire hive lock */
|
||||||
|
ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Get pointer to KeyCell */
|
/* Get pointer to KeyCell */
|
||||||
|
@ -1528,11 +1574,14 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
|
||||||
|
|
||||||
*ReturnLength = BufferLength;
|
*ReturnLength = BufferLength;
|
||||||
|
|
||||||
|
/* Release hive lock */
|
||||||
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
DPRINT("Return Status 0x%X\n", Status);
|
DPRINT("Return Status 0x%X\n", Status);
|
||||||
|
|
||||||
return Status;
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -483,19 +483,17 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
ULONG CreateDisposition;
|
ULONG CreateDisposition;
|
||||||
IO_STATUS_BLOCK IoSB;
|
IO_STATUS_BLOCK IoSB;
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
DWORD FreeOffset;
|
ULONG FreeOffset;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
//BOOLEAN Success;
|
|
||||||
PHBIN tmpBin;
|
PHBIN tmpBin;
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
|
|
||||||
IO_STATUS_BLOCK Iosb;
|
|
||||||
|
|
||||||
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew);
|
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew);
|
||||||
|
|
||||||
/* Duplicate Filename */
|
/* Duplicate Filename */
|
||||||
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
|
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -522,17 +520,22 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
|
DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
if ((CreateNew) && (IoSB.Information == FILE_CREATED))
|
if ((CreateNew) && (IoSB.Information == FILE_CREATED))
|
||||||
{
|
{
|
||||||
Status = CmiCreateNewRegFile(FileHandle);
|
Status = CmiCreateNewRegFile(FileHandle);
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
DPRINT("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
|
DPRINT1("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
|
||||||
return Status;
|
return(Status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
|
@ -546,7 +549,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
NtClose(FileHandle);
|
||||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -555,12 +558,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
FileOffset.u.HighPart = 0;
|
FileOffset.u.HighPart = 0;
|
||||||
FileOffset.u.LowPart = 0;
|
FileOffset.u.LowPart = 0;
|
||||||
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader);
|
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader);
|
||||||
Status = ZwReadFile(FileHandle,
|
Status = NtReadFile(FileHandle,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
// 0,
|
&IoSB,
|
||||||
&Iosb,
|
|
||||||
RegistryHive->HiveHeader,
|
RegistryHive->HiveHeader,
|
||||||
sizeof(HIVE_HEADER),
|
sizeof(HIVE_HEADER),
|
||||||
&FileOffset,
|
&FileOffset,
|
||||||
|
@ -576,7 +578,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = ZwQueryInformationFile(FileHandle,
|
Status = NtQueryInformationFile(FileHandle,
|
||||||
&IoSB,
|
&IoSB,
|
||||||
&fsi,
|
&fsi,
|
||||||
sizeof(fsi),
|
sizeof(fsi),
|
||||||
|
@ -600,9 +602,12 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
RegistryHive->FileSize = fsi.EndOfFile.u.LowPart;
|
RegistryHive->FileSize = fsi.EndOfFile.u.LowPart;
|
||||||
#ifdef WIN32_REGDBG
|
#ifdef WIN32_REGDBG
|
||||||
// assert(RegistryHive->FileSize);
|
// assert(RegistryHive->FileSize);
|
||||||
if (RegistryHive->FileSize) {
|
if (RegistryHive->FileSize)
|
||||||
|
{
|
||||||
RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1;
|
RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ObDereferenceObject(RegistryHive->FileObject);
|
ObDereferenceObject(RegistryHive->FileObject);
|
||||||
RtlFreeUnicodeString(&RegistryHive->Filename);
|
RtlFreeUnicodeString(&RegistryHive->Filename);
|
||||||
DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n");
|
DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n");
|
||||||
|
@ -670,12 +675,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
FileOffset.u.LowPart = 4096;
|
FileOffset.u.LowPart = 4096;
|
||||||
|
|
||||||
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]);
|
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]);
|
||||||
Status = ZwReadFile(FileHandle,
|
Status = NtReadFile(FileHandle,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
// 0,
|
&IoSB,
|
||||||
&Iosb,
|
|
||||||
(PVOID) RegistryHive->BlockList[0],
|
(PVOID) RegistryHive->BlockList[0],
|
||||||
RegistryHive->FileSize - 4096,
|
RegistryHive->FileSize - 4096,
|
||||||
&FileOffset,
|
&FileOffset,
|
||||||
|
@ -683,6 +687,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
|
|
||||||
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RegistryHive->FreeListSize = 0;
|
RegistryHive->FreeListSize = 0;
|
||||||
|
@ -741,7 +746,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive,
|
||||||
|
|
||||||
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew);
|
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -773,6 +778,7 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
BOOLEAN CreateNew)
|
BOOLEAN CreateNew)
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE Hive;
|
PREGISTRY_HIVE Hive;
|
||||||
|
KIRQL oldlvl;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
|
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
|
||||||
|
@ -781,7 +787,7 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
|
|
||||||
Hive = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_HIVE));
|
Hive = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_HIVE));
|
||||||
if (Hive == NULL)
|
if (Hive == NULL)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
DPRINT("Hive %x\n", Hive);
|
DPRINT("Hive %x\n", Hive);
|
||||||
|
|
||||||
|
@ -793,7 +799,7 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
if (Hive->HiveHeader == NULL)
|
if (Hive->HiveHeader == NULL)
|
||||||
{
|
{
|
||||||
ExFreePool(Hive);
|
ExFreePool(Hive);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Filename != NULL)
|
if (Filename != NULL)
|
||||||
|
@ -812,7 +818,12 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeInitializeSemaphore(&Hive->RegSem, 1, 1);
|
ExInitializeResourceLite(&Hive->HiveResource);
|
||||||
|
|
||||||
|
/* Add the new hive to the hive list */
|
||||||
|
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||||
|
InsertHeadList(&CmiHiveListHead, &Hive->HiveList);
|
||||||
|
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||||
|
|
||||||
VERIFY_REGISTRY_HIVE(Hive);
|
VERIFY_REGISTRY_HIVE(Hive);
|
||||||
|
|
||||||
|
@ -824,6 +835,30 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||||
|
{
|
||||||
|
KIRQL oldlvl;
|
||||||
|
|
||||||
|
/* Remove hive from hive list */
|
||||||
|
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||||
|
RemoveEntryList(&RegistryHive->HiveList);
|
||||||
|
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: Remove attached keys and values */
|
||||||
|
|
||||||
|
|
||||||
|
/* Release hive header */
|
||||||
|
ExFreePool(RegistryHive->HiveHeader);
|
||||||
|
|
||||||
|
/* Release hive */
|
||||||
|
ExFreePool(RegistryHive);
|
||||||
|
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
|
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
|
||||||
PKEY_CELL KeyCell)
|
PKEY_CELL KeyCell)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: registry.c,v 1.77 2002/11/13 05:18:03 robd Exp $
|
/* $Id: registry.c,v 1.78 2002/11/26 15:31:41 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -33,6 +33,9 @@ POBJECT_TYPE CmiKeyType = NULL;
|
||||||
PREGISTRY_HIVE CmiVolatileHive = NULL;
|
PREGISTRY_HIVE CmiVolatileHive = NULL;
|
||||||
KSPIN_LOCK CmiKeyListLock;
|
KSPIN_LOCK CmiKeyListLock;
|
||||||
|
|
||||||
|
LIST_ENTRY CmiHiveListHead;
|
||||||
|
KSPIN_LOCK CmiHiveListLock;
|
||||||
|
|
||||||
static PKEY_OBJECT CmiRootKey = NULL;
|
static PKEY_OBJECT CmiRootKey = NULL;
|
||||||
static PKEY_OBJECT CmiMachineKey = NULL;
|
static PKEY_OBJECT CmiMachineKey = NULL;
|
||||||
static PKEY_OBJECT CmiUserKey = NULL;
|
static PKEY_OBJECT CmiUserKey = NULL;
|
||||||
|
@ -42,6 +45,7 @@ static GENERIC_MAPPING CmiKeyMapping =
|
||||||
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
|
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CmiCheckKey(BOOLEAN Verbose,
|
CmiCheckKey(BOOLEAN Verbose,
|
||||||
HANDLE Key);
|
HANDLE Key);
|
||||||
|
@ -271,11 +275,15 @@ CmInitializeRegistry(VOID)
|
||||||
CmiKeyType->DuplicationNotify = NULL;
|
CmiKeyType->DuplicationNotify = NULL;
|
||||||
RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
|
RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
|
||||||
|
|
||||||
|
/* Initialize the hive list */
|
||||||
|
InitializeListHead(&CmiHiveListHead);
|
||||||
|
KeInitializeSpinLock(&CmiHiveListLock);
|
||||||
|
|
||||||
/* Build volatile registry store */
|
/* Build volatile registry store */
|
||||||
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
|
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
|
||||||
assert(NT_SUCCESS(Status));
|
assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Build the Root Key Object */
|
/* Create '\Registry' key. */
|
||||||
RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME);
|
RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME);
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
|
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
|
||||||
Status = ObCreateObject(&RootKeyHandle,
|
Status = ObCreateObject(&RootKeyHandle,
|
||||||
|
@ -307,7 +315,7 @@ CmInitializeRegistry(VOID)
|
||||||
|
|
||||||
/* Create initial predefined symbolic links */
|
/* Create initial predefined symbolic links */
|
||||||
|
|
||||||
/* HKEY_LOCAL_MACHINE */
|
/* Create '\Registry\Machine' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -334,7 +342,7 @@ CmInitializeRegistry(VOID)
|
||||||
CmiAddKeyToList(CmiRootKey, NewKey);
|
CmiAddKeyToList(CmiRootKey, NewKey);
|
||||||
CmiMachineKey = NewKey;
|
CmiMachineKey = NewKey;
|
||||||
|
|
||||||
/* HKEY_USERS */
|
/* Create '\Registry\User' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -361,7 +369,7 @@ CmInitializeRegistry(VOID)
|
||||||
CmiAddKeyToList(CmiRootKey, NewKey);
|
CmiAddKeyToList(CmiRootKey, NewKey);
|
||||||
CmiUserKey = NewKey;
|
CmiUserKey = NewKey;
|
||||||
|
|
||||||
/* Create '\\Registry\\Machine\\HARDWARE' key. */
|
/* Create '\Registry\Machine\HARDWARE' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -388,7 +396,7 @@ CmInitializeRegistry(VOID)
|
||||||
CmiAddKeyToList(CmiMachineKey, NewKey);
|
CmiAddKeyToList(CmiMachineKey, NewKey);
|
||||||
CmiHardwareKey = NewKey;
|
CmiHardwareKey = NewKey;
|
||||||
|
|
||||||
/* Create '\\Registry\\Machine\\HARDWARE\\DESCRIPTION' key. */
|
/* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -414,7 +422,7 @@ CmInitializeRegistry(VOID)
|
||||||
memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION"));
|
memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION"));
|
||||||
CmiAddKeyToList(CmiHardwareKey, NewKey);
|
CmiAddKeyToList(CmiHardwareKey, NewKey);
|
||||||
|
|
||||||
/* Create '\\Registry\\Machine\\HARDWARE\\DEVICEMAP' key. */
|
/* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -440,7 +448,7 @@ CmInitializeRegistry(VOID)
|
||||||
memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP"));
|
memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP"));
|
||||||
CmiAddKeyToList(CmiHardwareKey,NewKey);
|
CmiAddKeyToList(CmiHardwareKey,NewKey);
|
||||||
|
|
||||||
/* Create '\\Registry\\Machine\\HARDWARE\\RESOURCEMAP' key. */
|
/* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
|
||||||
Status = ObCreateObject(&KeyHandle,
|
Status = ObCreateObject(&KeyHandle,
|
||||||
STANDARD_RIGHTS_REQUIRED,
|
STANDARD_RIGHTS_REQUIRED,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -477,7 +485,9 @@ CmInit2(PCHAR CommandLine)
|
||||||
PCHAR p1, p2;
|
PCHAR p1, p2;
|
||||||
ULONG PiceStart;
|
ULONG PiceStart;
|
||||||
|
|
||||||
/* FIXME: Store current command line */
|
/* FIXME: Store system start options */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Create the 'CurrentControlSet' link. */
|
/* Create the 'CurrentControlSet' link. */
|
||||||
CmiCreateCurrentControlSetLink();
|
CmiCreateCurrentControlSetLink();
|
||||||
|
@ -655,9 +665,9 @@ CmiConnectHive(PWSTR FileName,
|
||||||
|
|
||||||
if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
|
if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
|
||||||
{
|
{
|
||||||
/* FIXME: Cleanup from CmiCreateRegistryHive() */
|
|
||||||
DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
|
DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
|
||||||
ZwClose(NewKey);
|
ZwClose(NewKey);
|
||||||
|
CmiRemoveRegistryHive(RegistryHive);
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -666,11 +676,11 @@ CmiConnectHive(PWSTR FileName,
|
||||||
|
|
||||||
if ((NewKey->Name == NULL) && (strlen(KeyName) != 0))
|
if ((NewKey->Name == NULL) && (strlen(KeyName) != 0))
|
||||||
{
|
{
|
||||||
/* FIXME: Cleanup from CmiCreateRegistryHive() */
|
|
||||||
DPRINT("strlen(KeyName) %d\n", strlen(KeyName));
|
DPRINT("strlen(KeyName) %d\n", strlen(KeyName));
|
||||||
if (NewKey->SubKeys != NULL)
|
if (NewKey->SubKeys != NULL)
|
||||||
ExFreePool(NewKey->SubKeys);
|
ExFreePool(NewKey->SubKeys);
|
||||||
ZwClose(NewKey);
|
ZwClose(NewKey);
|
||||||
|
CmiRemoveRegistryHive(RegistryHive);
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,39 +739,163 @@ CmiInitializeHive(PWSTR FileName,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiInitHives(BOOLEAN SetUpBoot)
|
CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
{
|
{
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING KeyName;
|
||||||
|
UNICODE_STRING ValueName;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
WCHAR ConfigPath[MAX_PATH];
|
||||||
|
|
||||||
|
ULONG BufferSize;
|
||||||
|
ULONG ResultSize;
|
||||||
|
PWSTR EndPtr;
|
||||||
|
|
||||||
|
|
||||||
DPRINT("CmiInitHives() called\n");
|
DPRINT("CmiInitHives() called\n");
|
||||||
|
|
||||||
|
if (SetUpBoot == TRUE)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeStringFromLiteral(&KeyName,
|
||||||
|
L"\\Registry\\Machine\\HARDWARE");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&KeyName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenKey(&KeyHandle,
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeStringFromLiteral(&ValueName,
|
||||||
|
L"InstallPath");
|
||||||
|
|
||||||
|
BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
|
||||||
|
ValueInfo = ExAllocatePool(PagedPool,
|
||||||
|
BufferSize);
|
||||||
|
if (ValueInfo == NULL)
|
||||||
|
{
|
||||||
|
NtClose(KeyHandle);
|
||||||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtQueryValueKey(KeyHandle,
|
||||||
|
&ValueName,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
ValueInfo,
|
||||||
|
BufferSize,
|
||||||
|
&ResultSize);
|
||||||
|
NtClose(KeyHandle);
|
||||||
|
if (ValueInfo == NULL)
|
||||||
|
{
|
||||||
|
ExFreePool(ValueInfo);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(ConfigPath,
|
||||||
|
ValueInfo->Data,
|
||||||
|
ValueInfo->DataLength);
|
||||||
|
ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0;
|
||||||
|
ExFreePool(ValueInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wcscpy(ConfigPath, L"\\SystemRoot\\system32\\config");
|
||||||
|
}
|
||||||
|
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||||
|
|
||||||
|
EndPtr = ConfigPath + wcslen(ConfigPath);
|
||||||
|
|
||||||
CmiDoVerify = TRUE;
|
CmiDoVerify = TRUE;
|
||||||
|
|
||||||
/* FIXME: Delete temporary \Registry\Machine\System */
|
/* FIXME: Save boot log */
|
||||||
|
|
||||||
|
/* FIXME: Rename \Registry\Machine\System */
|
||||||
|
|
||||||
/* Connect the SYSTEM hive */
|
/* Connect the SYSTEM hive */
|
||||||
/* FIXME: Don't overwrite the existing 'System' hive yet */
|
// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot);
|
||||||
// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey);
|
|
||||||
// assert(NT_SUCCESS(Status));
|
// assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
|
/* FIXME: Synchronize old and new system hive (??) */
|
||||||
|
|
||||||
|
/* FIXME: Delete old system hive */
|
||||||
|
|
||||||
/* Connect the SOFTWARE hive */
|
/* Connect the SOFTWARE hive */
|
||||||
Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey, SetUpBoot);
|
wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME);
|
||||||
|
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||||
|
|
||||||
|
// Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey, SetUpBoot);
|
||||||
|
Status = CmiInitializeHive(ConfigPath,
|
||||||
|
REG_SOFTWARE_KEY_NAME,
|
||||||
|
"Software",
|
||||||
|
CmiMachineKey,
|
||||||
|
SetUpBoot);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
//assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Connect the SAM hive */
|
/* Connect the SAM hive */
|
||||||
Status = CmiInitializeHive(SAM_REG_FILE,REG_SAM_KEY_NAME, "Sam", CmiMachineKey, SetUpBoot);
|
wcscpy(EndPtr, REG_SAM_FILE_NAME);
|
||||||
|
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||||
|
|
||||||
|
// Status = CmiInitializeHive(SAM_REG_FILE, REG_SAM_KEY_NAME, "Sam", CmiMachineKey, SetUpBoot);
|
||||||
|
Status = CmiInitializeHive(ConfigPath,
|
||||||
|
REG_SAM_KEY_NAME,
|
||||||
|
"Sam",
|
||||||
|
CmiMachineKey,
|
||||||
|
SetUpBoot);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
//assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Connect the SECURITY hive */
|
/* Connect the SECURITY hive */
|
||||||
Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey, SetUpBoot);
|
wcscpy(EndPtr, REG_SEC_FILE_NAME);
|
||||||
|
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||||
|
// Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey, SetUpBoot);
|
||||||
|
Status = CmiInitializeHive(ConfigPath,
|
||||||
|
REG_SEC_KEY_NAME,
|
||||||
|
"Security",
|
||||||
|
CmiMachineKey,
|
||||||
|
SetUpBoot);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
//assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* Connect the DEFAULT hive */
|
/* Connect the DEFAULT hive */
|
||||||
Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey, SetUpBoot);
|
wcscpy(EndPtr, REG_USER_FILE_NAME);
|
||||||
|
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
||||||
|
|
||||||
|
// Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey, SetUpBoot);
|
||||||
|
Status = CmiInitializeHive(ConfigPath,
|
||||||
|
REG_USER_KEY_NAME,
|
||||||
|
".Default",
|
||||||
|
CmiUserKey,
|
||||||
|
SetUpBoot);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
|
||||||
|
}
|
||||||
//assert(NT_SUCCESS(Status));
|
//assert(NT_SUCCESS(Status));
|
||||||
|
|
||||||
/* FIXME : initialize standards symbolic links */
|
/* FIXME : initialize standards symbolic links */
|
||||||
|
|
||||||
// CmiCheckRegistry(TRUE);
|
// CmiCheckRegistry(TRUE);
|
||||||
|
|
||||||
|
/* FIXME: Start automatic hive syncronization */
|
||||||
|
|
||||||
DPRINT("CmiInitHives() done\n");
|
DPRINT("CmiInitHives() done\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -771,7 +905,41 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
VOID
|
VOID
|
||||||
CmShutdownRegistry(VOID)
|
CmShutdownRegistry(VOID)
|
||||||
{
|
{
|
||||||
DPRINT("CmShutdownRegistry() called\n");
|
PREGISTRY_HIVE Hive;
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
KIRQL oldlvl;
|
||||||
|
|
||||||
|
DPRINT1("CmShutdownRegistry() called\n");
|
||||||
|
|
||||||
|
/* FIXME: Stop automatic hive syncronization */
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
||||||
|
Entry = CmiHiveListHead.Flink;
|
||||||
|
while (Entry != &CmiHiveListHead)
|
||||||
|
{
|
||||||
|
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
|
||||||
|
|
||||||
|
if (Hive->Flags & HIVE_VOLATILE)
|
||||||
|
{
|
||||||
|
DPRINT1("Volatile hive\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Flush non-volatile hive '%wZ'\n", &Hive->Filename);
|
||||||
|
|
||||||
|
/* Flush non-volatile hive */
|
||||||
|
|
||||||
|
/* Dereference file */
|
||||||
|
ObDereferenceObject(Hive->FileObject);
|
||||||
|
Hive->FileObject = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
}
|
||||||
|
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
||||||
|
|
||||||
|
DPRINT1(" *** System stopped ***\n");
|
||||||
|
for (;;);
|
||||||
|
|
||||||
/* Note:
|
/* Note:
|
||||||
* Don't call UNIMPLEMENTED() here since this function is
|
* Don't call UNIMPLEMENTED() here since this function is
|
||||||
|
|
Loading…
Reference in a new issue