From a76689e99c1c43ad3f44c259a73565dd5b1601c6 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 26 Nov 2002 15:31:41 +0000 Subject: [PATCH] Use ERESOURCE to lock registry hives. Keep open hives in a global list. svn path=/trunk/; revision=3794 --- reactos/ntoskrnl/cm/cm.h | 17 +- reactos/ntoskrnl/cm/ntfunc.c | 433 ++++++++++++++++++--------------- reactos/ntoskrnl/cm/regfile.c | 133 ++++++---- reactos/ntoskrnl/cm/registry.c | 206 ++++++++++++++-- reactos/ntoskrnl/cm/rtlfunc.c | 2 +- 5 files changed, 528 insertions(+), 263 deletions(-) diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 69a345d1744..3799acc8316 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -26,6 +26,12 @@ #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM" #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_HBIN_DATA_OFFSET 32 #define REG_BIN_ID 0x6e696268 @@ -228,6 +234,7 @@ typedef struct _DATA_CELL typedef struct _REGISTRY_HIVE { + LIST_ENTRY HiveList; ULONG Flags; UNICODE_STRING Filename; ULONG FileSize; @@ -240,8 +247,8 @@ typedef struct _REGISTRY_HIVE ULONG FreeListMax; PCELL_HEADER *FreeList; BLOCK_OFFSET *FreeListOffset; -// KSPIN_LOCK RegLock; - KSEMAPHORE RegSem; + ERESOURCE HiveResource; + // NTSTATUS (*Extend)(ULONG NewSize); // PVOID (*Flush)(VOID); } REGISTRY_HIVE, *PREGISTRY_HIVE; @@ -314,6 +321,9 @@ extern PREGISTRY_HIVE CmiVolatileHive; extern POBJECT_TYPE CmiKeyType; extern KSPIN_LOCK CmiKeyListLock; +extern LIST_ENTRY CmiHiveListHead; +extern KSPIN_LOCK CmiHiveListLock; + VOID CmiVerifyBinCell(PHBIN BinCell); @@ -376,6 +386,9 @@ CmiCreateRegistryHive(PWSTR Filename, PREGISTRY_HIVE *RegistryHive, BOOLEAN CreateNew); +NTSTATUS +CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive); + ULONG CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive, IN PKEY_CELL KeyCell); diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 43217f3a8ec..dd9d8ea7832 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -38,12 +38,12 @@ static BOOLEAN CmiRegistryInitialized = FALSE; NTSTATUS STDCALL NtCreateKey(OUT PHANDLE KeyHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - IN ULONG TitleIndex, - IN PUNICODE_STRING Class, - IN ULONG CreateOptions, - OUT PULONG Disposition) + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class, + IN ULONG CreateOptions, + OUT PULONG Disposition) { UNICODE_STRING RemainingPath; PKEY_OBJECT KeyObject; @@ -52,17 +52,19 @@ NtCreateKey(OUT PHANDLE KeyHandle, PWSTR End; DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n", - ObjectAttributes->ObjectName, - KeyHandle, - ObjectAttributes->RootDirectory); + ObjectAttributes->ObjectName, + KeyHandle, + ObjectAttributes->RootDirectory); /* 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)) { - return Status; + return(Status); } DPRINT("RemainingPath %wZ\n", &RemainingPath); @@ -73,7 +75,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE) { ObDereferenceObject(Object); - return STATUS_UNSUCCESSFUL; + return(STATUS_UNSUCCESSFUL); } if (Disposition) @@ -112,7 +114,9 @@ NtCreateKey(OUT PHANDLE KeyHandle, (PVOID*)&KeyObject); if (!NT_SUCCESS(Status)) - return(Status); + { + return(Status); + } KeyObject->ParentKey = Object; @@ -125,7 +129,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, KeyObject->NumberOfSubKeys = 0; KeyObject->SizeOfSubKeys = 0; KeyObject->SubKeys = NULL; -// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql); + + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + /* add key to subkeys of parent if needed */ Status = CmiAddSubKey(KeyObject->RegistryHive, KeyObject->ParentKey, @@ -138,6 +145,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, if (!NT_SUCCESS(Status)) { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); ObDereferenceObject(Object); return STATUS_UNSUCCESSFUL; @@ -164,7 +172,9 @@ NtCreateKey(OUT PHANDLE KeyHandle, } CmiAddKeyToList(KeyObject->ParentKey, KeyObject); -// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql); + + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); ObDereferenceObject(Object); @@ -199,6 +209,9 @@ NtDeleteKey(IN HANDLE KeyHandle) return Status; } + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* 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 */ ObDereferenceObject(KeyObject); + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + return STATUS_SUCCESS; } @@ -238,13 +254,13 @@ NtEnumerateKey( PDATA_CELL pClassData; DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n", - KeyHandle, - Index, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); - + KeyHandle, + Index, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_ENUMERATE_SUB_KEYS, @@ -255,62 +271,68 @@ NtEnumerateKey( if (!NT_SUCCESS(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); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - + /* Get pointer to SubKey */ if (Index >= KeyCell->NumberOfSubKeys) - { - if (RegistryHive == CmiVolatileHive) - { - ObDereferenceObject (KeyObject); - DPRINT("No more volatile entries\n"); - return STATUS_NO_MORE_ENTRIES; - } - else - { - ULONG i; - PKEY_OBJECT CurKey = NULL; - - /* Search volatile keys */ - for (i = 0; i < KeyObject->NumberOfSubKeys; i++) - { - CurKey = KeyObject->SubKeys[i]; - if (CurKey->RegistryHive == CmiVolatileHive) - { - if (Index-- == KeyObject->NumberOfSubKeys) - break; - } - } - if(Index >= KeyCell->NumberOfSubKeys) - { - ObDereferenceObject (KeyObject); - DPRINT("No more non-volatile entries\n"); - return STATUS_NO_MORE_ENTRIES; - } - SubKeyCell = CurKey->KeyCell; - } - } + { + if (RegistryHive == CmiVolatileHive) + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more volatile entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } + else + { + ULONG i; + PKEY_OBJECT CurKey = NULL; + + /* Search volatile keys */ + for (i = 0; i < KeyObject->NumberOfSubKeys; i++) + { + CurKey = KeyObject->SubKeys[i]; + if (CurKey->RegistryHive == CmiVolatileHive) + { + if (Index-- == KeyObject->NumberOfSubKeys) + break; + } + } + if (Index >= KeyCell->NumberOfSubKeys) + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more non-volatile entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } + SubKeyCell = CurKey->KeyCell; + } + } else - { - HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); - SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive, - HashTableBlock, - Index); - } + { + HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL); + SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive, + HashTableBlock, + Index); + } if (SubKeyCell == NULL) - { - ObDereferenceObject (KeyObject); - DPRINT("No more entries\n"); - return STATUS_NO_MORE_ENTRIES; - } + { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + DPRINT("No more entries\n"); + return(STATUS_NO_MORE_ENTRIES); + } Status = STATUS_SUCCESS; switch (KeyInformationClass) @@ -417,11 +439,13 @@ NtEnumerateKey( break; } CmiReleaseBlock(RegistryHive, SubKeyCell); - ObDereferenceObject (KeyObject); + + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); DPRINT("Returning status %x\n", Status); - return Status; + return(Status); } @@ -444,12 +468,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, PKEY_VALUE_FULL_INFORMATION ValueFullInformation; DPRINT("KH %x I %d KVIC %x KVI %x L %d RL %x\n", - KeyHandle, - Index, - KeyValueInformationClass, - KeyValueInformation, - Length, - ResultLength); + KeyHandle, + Index, + KeyValueInformationClass, + KeyValueInformation, + Length, + ResultLength); /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, @@ -464,12 +488,15 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, return Status; } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - + /* Get Value block of interest */ Status = CmiGetValueFromKeyByIndex(RegistryHive, KeyCell, @@ -478,10 +505,12 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } - else if (ValueCell != NULL) + + if (ValueCell != NULL) { switch (KeyValueInformationClass) { @@ -588,6 +617,8 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, { Status = STATUS_UNSUCCESSFUL; } + + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; @@ -597,23 +628,22 @@ NtEnumerateValueKey(IN HANDLE KeyHandle, NTSTATUS STDCALL NtFlushKey(IN HANDLE KeyHandle) { - NTSTATUS Status; - PKEY_OBJECT KeyObject; - PREGISTRY_HIVE RegistryHive; - WCHAR LogName[MAX_PATH]; - UNICODE_STRING TmpFileName; - HANDLE FileHandle; - // HANDLE FileHandleLog; - OBJECT_ATTRIBUTES ObjectAttributes; - // KIRQL OldIrql; - LARGE_INTEGER fileOffset; - DWORD * pEntDword; - ULONG i; + NTSTATUS Status; + PKEY_OBJECT KeyObject; + PREGISTRY_HIVE RegistryHive; + WCHAR LogName[MAX_PATH]; + UNICODE_STRING TmpFileName; + HANDLE FileHandle; +// HANDLE FileHandleLog; + OBJECT_ATTRIBUTES ObjectAttributes; + LARGE_INTEGER fileOffset; + DWORD * pEntDword; + ULONG i; DPRINT("KeyHandle %x\n", KeyHandle); - /* Verify that the handle is valid and is a registry key */ - Status = ObReferenceObjectByHandle(KeyHandle, + /* Verify that the handle is valid and is a registry key */ + Status = ObReferenceObjectByHandle(KeyHandle, KEY_QUERY_VALUE, CmiKeyType, UserMode, @@ -625,19 +655,22 @@ NtFlushKey(IN HANDLE KeyHandle) return Status; } + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); RegistryHive = KeyObject->RegistryHive; -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); + /* Then write changed blocks in .log */ wcscpy(LogName,RegistryHive->Filename.Buffer); wcscat(LogName,L".log"); RtlInitUnicodeString (&TmpFileName, LogName); InitializeObjectAttributes(&ObjectAttributes, - &TmpFileName, - 0, - NULL, - NULL); + &TmpFileName, + 0, + NULL, + NULL); /* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files so we can't create log file @@ -721,28 +754,28 @@ END FIXME*/ NULL, 0, FILE_SYNCHRONOUS_IO_NONALERT); - if (!NT_SUCCESS(Status)) { + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } RegistryHive->HiveHeader->Version++; - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - 0, - 0); - + Status = ZwWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + 0, + 0); if (!NT_SUCCESS(Status)) { ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } @@ -750,35 +783,33 @@ END FIXME*/ /* Update changed blocks in file */ fileOffset.u.HighPart = 0; for (i = 0; i < RegistryHive->BlockListSize ; i++) - { - if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime + { + if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime > RegistryHive->HiveHeader->DateModified.dwHighDateTime - || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime + || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime == RegistryHive->HiveHeader->DateModified.dwHighDateTime - && RegistryHive->BlockList[i]->DateModified.dwLowDateTime - > RegistryHive->HiveHeader->DateModified.dwLowDateTime - ) - ) + && RegistryHive->BlockList[i]->DateModified.dwLowDateTime + > RegistryHive->HiveHeader->DateModified.dwLowDateTime)) + { + fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096; + Status = NtWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->BlockList[i], + RegistryHive->BlockList[i]->BlockSize, + &fileOffset, + 0); + if (!NT_SUCCESS(Status)) { - fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096; - Status = NtWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->BlockList[i], - RegistryHive->BlockList[i]->BlockSize , - &fileOffset, - 0); - - if (!NT_SUCCESS(Status)) - { - ZwClose(FileHandle); - ObDereferenceObject(KeyObject); - return Status; - } + ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); + return(Status); } - } + } + } /* Change version in header */ RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version; @@ -794,25 +825,26 @@ END FIXME*/ /* Write new header */ fileOffset.u.LowPart = 0; - Status = ZwWriteFile(FileHandle, - 0, - 0, - 0, - 0, - RegistryHive->HiveHeader, - sizeof(HIVE_HEADER), - &fileOffset, - 0); + Status = ZwWriteFile(FileHandle, + 0, + 0, + 0, + 0, + RegistryHive->HiveHeader, + sizeof(HIVE_HEADER), + &fileOffset, + 0); if (!NT_SUCCESS(Status)) { ZwClose(FileHandle); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } ZwClose(FileHandle); -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return STATUS_SUCCESS; } @@ -893,12 +925,12 @@ NtQueryKey(IN HANDLE KeyHandle, NTSTATUS Status; DPRINT("KH %x KIC %x KI %x L %d RL %x\n", - KeyHandle, - KeyInformationClass, - KeyInformation, - Length, - ResultLength); - + KeyHandle, + KeyInformationClass, + KeyInformation, + Length, + ResultLength); + /* Verify that the handle is valid and is a registry key */ Status = ObReferenceObjectByHandle(KeyHandle, KEY_READ, @@ -906,12 +938,14 @@ NtQueryKey(IN HANDLE KeyHandle, UserMode, (PVOID *) &KeyObject, NULL); - if (!NT_SUCCESS(Status)) { return Status; } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ @@ -1023,11 +1057,13 @@ NtQueryKey(IN HANDLE KeyHandle, break; } + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return Status; } + NTSTATUS STDCALL NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, @@ -1067,22 +1103,27 @@ NtQueryValueKey(IN HANDLE KeyHandle, return Status; } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ KeyCell = KeyObject->KeyCell; RegistryHive = KeyObject->RegistryHive; - /* Get Value block of interest */ - Status = CmiScanKeyForValue(RegistryHive, - KeyCell, - ValueName2, - &ValueCell,NULL); + /* Get Value block of interest */ + Status = CmiScanKeyForValue(RegistryHive, + KeyCell, + ValueName2, + &ValueCell, + NULL); if (!NT_SUCCESS(Status)) { DPRINT("CmiScanKeyForValue() failed with status %x\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); - return Status; + return(Status); } else if (ValueCell != NULL) { @@ -1165,21 +1206,21 @@ NtQueryValueKey(IN HANDLE KeyHandle, mbstowcs(ValueFullInformation->Name, ValueCell->Name,ValueCell->NameSize*2); ValueFullInformation->Name[ValueCell->NameSize] = 0; if (ValueCell->DataSize > 0) - { - DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - DataCell->Data, - ValueCell->DataSize & LONG_MAX); - CmiReleaseBlock(RegistryHive, DataCell); - } + { + DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL); + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + DataCell->Data, + ValueCell->DataSize & LONG_MAX); + CmiReleaseBlock(RegistryHive, DataCell); + } else - { - RtlCopyMemory((PCHAR) ValueFullInformation - + ValueFullInformation->DataOffset, - &ValueCell->DataOffset, - ValueCell->DataSize & LONG_MAX); - } + { + RtlCopyMemory((PCHAR) ValueFullInformation + + ValueFullInformation->DataOffset, + &ValueCell->DataOffset, + ValueCell->DataSize & LONG_MAX); + } } break; } @@ -1189,8 +1230,9 @@ NtQueryValueKey(IN HANDLE KeyHandle, Status = STATUS_OBJECT_NAME_NOT_FOUND; } + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); - + return Status; } @@ -1214,7 +1256,6 @@ NtSetValueKey(IN HANDLE KeyHandle, PDATA_CELL NewDataCell; PHBIN pBin; ULONG DesiredAccess; -// KIRQL OldIrql; DPRINT("KeyHandle %x ValueName %S Type %d\n", KeyHandle, ValueName? ValueName->Buffer : NULL, Type); @@ -1236,6 +1277,9 @@ NtSetValueKey(IN HANDLE KeyHandle, if (!NT_SUCCESS(Status)) return(Status); + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to key cell */ @@ -1250,12 +1294,11 @@ NtSetValueKey(IN HANDLE KeyHandle, { DPRINT1("Value not found. Status 0x%X\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return(Status); } -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); - if (ValueCell == NULL) { Status = CmiAddValueToKey(RegistryHive, @@ -1269,6 +1312,7 @@ NtSetValueKey(IN HANDLE KeyHandle, { DPRINT1("Cannot add value. Status 0x%X\n", Status); + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); return(Status); } @@ -1338,8 +1382,7 @@ NtSetValueKey(IN HANDLE KeyHandle, } } -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); - + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); ObDereferenceObject(KeyObject); DPRINT("Return Status 0x%X\n", Status); @@ -1350,14 +1393,11 @@ NtSetValueKey(IN HANDLE KeyHandle, NTSTATUS STDCALL NtDeleteValueKey(IN HANDLE KeyHandle, - IN PUNICODE_STRING ValueName) + IN PUNICODE_STRING ValueName) { - PREGISTRY_HIVE RegistryHive; CHAR ValueName2[MAX_PATH]; PKEY_OBJECT KeyObject; - PKEY_CELL KeyCell; NTSTATUS Status; -// KIRQL OldIrql; wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1); ValueName2[ValueName->Length>>1] = 0; @@ -1369,20 +1409,23 @@ NtDeleteValueKey(IN HANDLE KeyHandle, UserMode, (PVOID *)&KeyObject, NULL); - if (!NT_SUCCESS(Status)) { return Status; } + /* Acquire hive lock */ + ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); - /* Get pointer to KeyCell */ - KeyCell = KeyObject->KeyCell; - RegistryHive = KeyObject->RegistryHive; -// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql); - Status = CmiDeleteValueFromKey(RegistryHive, KeyCell, ValueName2); -// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql); + Status = CmiDeleteValueFromKey(KeyObject->RegistryHive, + KeyObject->KeyCell, + ValueName2); + + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); return Status; @@ -1425,11 +1468,11 @@ NtNotifyChangeKey( NTSTATUS STDCALL NtQueryMultipleValueKey(IN HANDLE KeyHandle, - IN OUT PKEY_VALUE_ENTRY ValueList, - IN ULONG NumberOfValues, - OUT PVOID Buffer, - IN OUT PULONG Length, - OUT PULONG ReturnLength) + IN OUT PKEY_VALUE_ENTRY ValueList, + IN ULONG NumberOfValues, + OUT PVOID Buffer, + IN OUT PULONG Length, + OUT PULONG ReturnLength) { PREGISTRY_HIVE RegistryHive; UCHAR ValueName[MAX_PATH]; @@ -1455,6 +1498,9 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, return(Status); } + /* Acquire hive lock */ + ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE); + VERIFY_KEY_OBJECT(KeyObject); /* Get pointer to KeyCell */ @@ -1528,11 +1574,14 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle, *ReturnLength = BufferLength; + /* Release hive lock */ + ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource); + ObDereferenceObject(KeyObject); DPRINT("Return Status 0x%X\n", Status); - return Status; + return(Status); } diff --git a/reactos/ntoskrnl/cm/regfile.c b/reactos/ntoskrnl/cm/regfile.c index 1ae26f70ee4..4587dc26b76 100644 --- a/reactos/ntoskrnl/cm/regfile.c +++ b/reactos/ntoskrnl/cm/regfile.c @@ -483,19 +483,17 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, ULONG CreateDisposition; IO_STATUS_BLOCK IoSB; HANDLE FileHandle; - DWORD FreeOffset; + ULONG FreeOffset; NTSTATUS Status; - //BOOLEAN Success; PHBIN tmpBin; ULONG i, j; - IO_STATUS_BLOCK Iosb; - DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew); /* Duplicate Filename */ Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename); - if (!NT_SUCCESS(Status)) { + if (!NT_SUCCESS(Status)) + { DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n"); return Status; } @@ -512,27 +510,32 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, CreateDisposition = FILE_OPEN; Status = NtCreateFile(&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &IoSB, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - CreateDisposition, - FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - - if ((CreateNew) && (IoSB.Information == FILE_CREATED)) + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoSB, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + CreateDisposition, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) { - Status = CmiCreateNewRegFile(FileHandle); + RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT1("NtCreateFile() failed (Status %lx)\n", Status); + return(Status); } - if (!NT_SUCCESS(Status)) + if ((CreateNew) && (IoSB.Information == FILE_CREATED)) { - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiCreateNewRegFile() - Failed with status %x.\n", Status); - return Status; + Status = CmiCreateNewRegFile(FileHandle); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT1("CmiCreateNewRegFile() - Failed with status %x.\n", Status); + return(Status); + } } Status = ObReferenceObjectByHandle(FileHandle, @@ -546,7 +549,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, if (!NT_SUCCESS(Status)) { - ZwClose(FileHandle); + NtClose(FileHandle); RtlFreeUnicodeString(&RegistryHive->Filename); DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status); return Status; @@ -555,12 +558,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, FileOffset.u.HighPart = 0; FileOffset.u.LowPart = 0; 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, - &Iosb, + &IoSB, RegistryHive->HiveHeader, sizeof(HIVE_HEADER), &FileOffset, @@ -576,11 +578,11 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, return Status; } - Status = ZwQueryInformationFile(FileHandle, - &IoSB, - &fsi, - sizeof(fsi), - FileStandardInformation); + Status = NtQueryInformationFile(FileHandle, + &IoSB, + &fsi, + sizeof(fsi), + FileStandardInformation); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); @@ -600,13 +602,16 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, RegistryHive->FileSize = fsi.EndOfFile.u.LowPart; #ifdef WIN32_REGDBG // assert(RegistryHive->FileSize); - if (RegistryHive->FileSize) { - RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; - } else { - ObDereferenceObject(RegistryHive->FileObject); - RtlFreeUnicodeString(&RegistryHive->Filename); - DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n"); - return STATUS_INSUFFICIENT_RESOURCES; + if (RegistryHive->FileSize) + { + RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; + } + else + { + ObDereferenceObject(RegistryHive->FileObject); + RtlFreeUnicodeString(&RegistryHive->Filename); + DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n"); + return STATUS_INSUFFICIENT_RESOURCES; } #else RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1; @@ -670,19 +675,19 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, FileOffset.u.LowPart = 4096; 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, - &Iosb, + &IoSB, (PVOID) RegistryHive->BlockList[0], RegistryHive->FileSize - 4096, - &FileOffset, - 0); + &FileOffset, + 0); assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status)); + NtClose(FileHandle); #endif RegistryHive->FreeListSize = 0; @@ -698,7 +703,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, { DPRINT("Bad BlockId %x, offset %x\n", tmpBin->BlockId, BlockOffset); //KeBugCheck(0); - return STATUS_INSUFFICIENT_RESOURCES; + return STATUS_INSUFFICIENT_RESOURCES; } assertmsg((tmpBin->BlockSize % 4096) == 0, ("BlockSize (0x%.08x) must be multiplum of 4K\n", tmpBin->BlockSize)); @@ -741,7 +746,7 @@ CmiInitPermanentRegistryHive(PREGISTRY_HIVE RegistryHive, 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) { PREGISTRY_HIVE Hive; + KIRQL oldlvl; NTSTATUS Status; DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename); @@ -781,7 +787,7 @@ CmiCreateRegistryHive(PWSTR Filename, Hive = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_HIVE)); if (Hive == NULL) - return STATUS_INSUFFICIENT_RESOURCES; + return(STATUS_INSUFFICIENT_RESOURCES); DPRINT("Hive %x\n", Hive); @@ -793,7 +799,7 @@ CmiCreateRegistryHive(PWSTR Filename, if (Hive->HiveHeader == NULL) { ExFreePool(Hive); - return STATUS_INSUFFICIENT_RESOURCES; + return(STATUS_INSUFFICIENT_RESOURCES); } if (Filename != NULL) @@ -812,8 +818,13 @@ CmiCreateRegistryHive(PWSTR Filename, 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); *RegistryHive = 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 CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive, PKEY_CELL KeyCell) diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index e52439e9e1f..2d002d1ef4e 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -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 * PROJECT: ReactOS kernel @@ -33,6 +33,9 @@ POBJECT_TYPE CmiKeyType = NULL; PREGISTRY_HIVE CmiVolatileHive = NULL; KSPIN_LOCK CmiKeyListLock; +LIST_ENTRY CmiHiveListHead; +KSPIN_LOCK CmiHiveListLock; + static PKEY_OBJECT CmiRootKey = NULL; static PKEY_OBJECT CmiMachineKey = NULL; static PKEY_OBJECT CmiUserKey = NULL; @@ -42,6 +45,7 @@ static GENERIC_MAPPING CmiKeyMapping = {KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS}; + VOID CmiCheckKey(BOOLEAN Verbose, HANDLE Key); @@ -271,11 +275,15 @@ CmInitializeRegistry(VOID) CmiKeyType->DuplicationNotify = NULL; RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key"); + /* Initialize the hive list */ + InitializeListHead(&CmiHiveListHead); + KeInitializeSpinLock(&CmiHiveListLock); + /* Build volatile registry store */ Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE); assert(NT_SUCCESS(Status)); - /* Build the Root Key Object */ + /* Create '\Registry' key. */ RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME); InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL); Status = ObCreateObject(&RootKeyHandle, @@ -307,7 +315,7 @@ CmInitializeRegistry(VOID) /* Create initial predefined symbolic links */ - /* HKEY_LOCAL_MACHINE */ + /* Create '\Registry\Machine' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -334,7 +342,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiRootKey, NewKey); CmiMachineKey = NewKey; - /* HKEY_USERS */ + /* Create '\Registry\User' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -361,7 +369,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiRootKey, NewKey); CmiUserKey = NewKey; - /* Create '\\Registry\\Machine\\HARDWARE' key. */ + /* Create '\Registry\Machine\HARDWARE' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -388,7 +396,7 @@ CmInitializeRegistry(VOID) CmiAddKeyToList(CmiMachineKey, NewKey); CmiHardwareKey = NewKey; - /* Create '\\Registry\\Machine\\HARDWARE\\DESCRIPTION' key. */ + /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -414,7 +422,7 @@ CmInitializeRegistry(VOID) memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION")); CmiAddKeyToList(CmiHardwareKey, NewKey); - /* Create '\\Registry\\Machine\\HARDWARE\\DEVICEMAP' key. */ + /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -440,7 +448,7 @@ CmInitializeRegistry(VOID) memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP")); CmiAddKeyToList(CmiHardwareKey,NewKey); - /* Create '\\Registry\\Machine\\HARDWARE\\RESOURCEMAP' key. */ + /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ Status = ObCreateObject(&KeyHandle, STANDARD_RIGHTS_REQUIRED, NULL, @@ -477,7 +485,9 @@ CmInit2(PCHAR CommandLine) PCHAR p1, p2; ULONG PiceStart; - /* FIXME: Store current command line */ + /* FIXME: Store system start options */ + + /* Create the 'CurrentControlSet' link. */ CmiCreateCurrentControlSetLink(); @@ -655,9 +665,9 @@ CmiConnectHive(PWSTR FileName, if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0)) { - /* FIXME: Cleanup from CmiCreateRegistryHive() */ DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys); ZwClose(NewKey); + CmiRemoveRegistryHive(RegistryHive); return(STATUS_INSUFFICIENT_RESOURCES); } @@ -666,11 +676,11 @@ CmiConnectHive(PWSTR FileName, if ((NewKey->Name == NULL) && (strlen(KeyName) != 0)) { - /* FIXME: Cleanup from CmiCreateRegistryHive() */ DPRINT("strlen(KeyName) %d\n", strlen(KeyName)); if (NewKey->SubKeys != NULL) ExFreePool(NewKey->SubKeys); ZwClose(NewKey); + CmiRemoveRegistryHive(RegistryHive); return(STATUS_INSUFFICIENT_RESOURCES); } @@ -729,39 +739,163 @@ CmiInitializeHive(PWSTR FileName, NTSTATUS CmiInitHives(BOOLEAN SetUpBoot) { + PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE KeyHandle; + NTSTATUS Status; + WCHAR ConfigPath[MAX_PATH]; + + ULONG BufferSize; + ULONG ResultSize; + PWSTR EndPtr; + + 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; - /* FIXME: Delete temporary \Registry\Machine\System */ + /* FIXME: Save boot log */ + + /* FIXME: Rename \Registry\Machine\System */ /* Connect the SYSTEM hive */ - /* FIXME: Don't overwrite the existing 'System' hive yet */ -// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey); +// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot); // assert(NT_SUCCESS(Status)); + /* FIXME: Synchronize old and new system hive (??) */ + + /* FIXME: Delete old system 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)); /* 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)); /* 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)); /* 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)); /* FIXME : initialize standards symbolic links */ // CmiCheckRegistry(TRUE); + /* FIXME: Start automatic hive syncronization */ + DPRINT("CmiInitHives() done\n"); return(STATUS_SUCCESS); @@ -771,7 +905,41 @@ CmiInitHives(BOOLEAN SetUpBoot) 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: * Don't call UNIMPLEMENTED() here since this function is diff --git a/reactos/ntoskrnl/cm/rtlfunc.c b/reactos/ntoskrnl/cm/rtlfunc.c index 13063dfa083..9678f62542f 100644 --- a/reactos/ntoskrnl/cm/rtlfunc.c +++ b/reactos/ntoskrnl/cm/rtlfunc.c @@ -190,7 +190,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo, ParamTable[1].DefaultType = REG_MULTI_SZ; Status = RtlQueryRegistryValues( - IN ULONG RelativeTo = RTL_REGISTRY_ABSOLUTE, + IN ULONG RelativeTo = RTL_REGISTRY_ABSOLUTE, IN PWSTR Path = Path, IN PRTL_QUERY_REGISTRY_TABLE QueryTable = ParamTable, IN PVOID Context = NULL, -- 2.17.1