diff --git a/reactos/ntoskrnl/cm/import.c b/reactos/ntoskrnl/cm/import.c index 48cfaacee5e..f20c3a4c4ea 100644 --- a/reactos/ntoskrnl/cm/import.c +++ b/reactos/ntoskrnl/cm/import.c @@ -91,20 +91,9 @@ CmImportSystemHive(PCHAR ChunkBase, { *RegistryHive = NULL; - DPRINT ("CmImportSystemHive() called\n"); - - if (strncmp (ChunkBase, "regf", 4)) - { - DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase); - return FALSE; - } - - DPRINT ("Found '%.*s' magic\n", 4, ChunkBase); - /* Import the binary system hive (non-volatile, offset-based, permanent) */ if (!CmImportBinaryHive (ChunkBase, ChunkSize, 0, RegistryHive)) { - DPRINT1 ("CmiImportBinaryHive() failed\n"); return FALSE; } @@ -125,123 +114,11 @@ CmImportHardwareHive(PCHAR ChunkBase, ULONG ChunkSize, OUT PEREGISTRY_HIVE *RegistryHive) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName; - HANDLE HardwareKey; - ULONG Disposition; - NTSTATUS Status; *RegistryHive = NULL; - DPRINT ("CmImportHardwareHive() called\n"); - - if (ChunkBase == NULL && - ChunkSize == 0) - { - /* Create '\Registry\Machine\HARDWARE' key. */ - RtlInitUnicodeString (&KeyName, - REG_HARDWARE_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwCreateKey (&HardwareKey, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status); - return FALSE; - } - ZwClose (HardwareKey); - - /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */ - RtlInitUnicodeString(&KeyName, - REG_DESCRIPTION_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwCreateKey (&HardwareKey, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status); - return FALSE; - } - ZwClose (HardwareKey); - - /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */ - RtlInitUnicodeString (&KeyName, - REG_DEVICEMAP_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwCreateKey (&HardwareKey, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status); - return FALSE; - } - ZwClose (HardwareKey); - - /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */ - RtlInitUnicodeString(&KeyName, - REG_RESOURCEMAP_KEY_NAME); - InitializeObjectAttributes (&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwCreateKey (&HardwareKey, - KEY_ALL_ACCESS, - &ObjectAttributes, - 0, - NULL, - REG_OPTION_VOLATILE, - &Disposition); - if (!NT_SUCCESS(Status)) - { - DPRINT1("NtCreateKey() failed, status: 0x%x\n", Status); - return FALSE; - } - ZwClose (HardwareKey); - - return TRUE; - } - - /* Check the hive magic */ - if (strncmp (ChunkBase, "regf", 4)) - { - DPRINT1 ("Found invalid '%.*s' magic\n", 4, ChunkBase); - return FALSE; - } - - DPRINT ("Found '%.*s' magic\n", 4, ChunkBase); - DPRINT ("ChunkBase %lx ChunkSize %lu\n", ChunkBase, ChunkSize); - /* Import the binary system hive (volatile, offset-based, permanent) */ if (!CmImportBinaryHive (ChunkBase, ChunkSize, HIVE_NO_FILE, RegistryHive)) { - DPRINT1 ("CmiImportBinaryHive() failed\n"); return FALSE; } diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index b32e7296253..dd3b5051b09 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -29,9 +29,6 @@ extern LIST_ENTRY CmiKeyObjectListHead; static BOOLEAN CmiRegistryInitialized = FALSE; -LIST_ENTRY CmiCallbackHead; -FAST_MUTEX CmiCallbackLock; - /* FUNCTIONS ****************************************************************/ NTSTATUS @@ -131,151 +128,6 @@ CmpCreateHandle(PVOID ObjectBody, return STATUS_UNSUCCESSFUL; } -/* - * @implemented - */ -NTSTATUS STDCALL -CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function, - IN PVOID Context, - IN OUT PLARGE_INTEGER Cookie) -{ - PREGISTRY_CALLBACK Callback; - - PAGED_CODE(); - - ASSERT(Function && Cookie); - - Callback = ExAllocatePoolWithTag(PagedPool, - sizeof(REGISTRY_CALLBACK), - TAG('C', 'M', 'c', 'b')); - if(Callback != NULL) - { - /* initialize the callback */ - ExInitializeRundownProtection(&Callback->RundownRef); - Callback->Function = Function; - Callback->Context = Context; - Callback->PendingDelete = FALSE; - - /* add it to the callback list and receive a cookie for the callback */ - ExAcquireFastMutex(&CmiCallbackLock); - /* FIXME - to receive a unique cookie we'll just return the pointer to the - callback object */ - Callback->Cookie.QuadPart = (ULONG_PTR)Callback; - InsertTailList(&CmiCallbackHead, &Callback->ListEntry); - - ExReleaseFastMutex(&CmiCallbackLock); - - *Cookie = Callback->Cookie; - return STATUS_SUCCESS; - } - - return STATUS_INSUFFICIENT_RESOURCES; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -CmUnRegisterCallback(IN LARGE_INTEGER Cookie) -{ - PLIST_ENTRY CurrentEntry; - - PAGED_CODE(); - - ExAcquireFastMutex(&CmiCallbackLock); - - for(CurrentEntry = CmiCallbackHead.Flink; - CurrentEntry != &CmiCallbackHead; - CurrentEntry = CurrentEntry->Flink) - { - PREGISTRY_CALLBACK CurrentCallback; - - CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); - if(CurrentCallback->Cookie.QuadPart == Cookie.QuadPart) - { - if(!CurrentCallback->PendingDelete) - { - /* found the callback, don't unlink it from the list yet so we don't screw - the calling loop */ - CurrentCallback->PendingDelete = TRUE; - ExReleaseFastMutex(&CmiCallbackLock); - - /* if the callback is currently executing, wait until it finished */ - ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef); - - /* time to unlink it. It's now safe because every attempt to acquire a - runtime protection on this callback will fail */ - ExAcquireFastMutex(&CmiCallbackLock); - RemoveEntryList(&CurrentCallback->ListEntry); - ExReleaseFastMutex(&CmiCallbackLock); - - /* free the callback */ - ExFreePool(CurrentCallback); - return STATUS_SUCCESS; - } - else - { - /* pending delete, pretend like it already is deleted */ - ExReleaseFastMutex(&CmiCallbackLock); - return STATUS_UNSUCCESSFUL; - } - } - } - - ExReleaseFastMutex(&CmiCallbackLock); - - return STATUS_UNSUCCESSFUL; -} - - -NTSTATUS -CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, - IN PVOID Argument2) -{ - PLIST_ENTRY CurrentEntry; - NTSTATUS Status = STATUS_SUCCESS; - - PAGED_CODE(); - - ExAcquireFastMutex(&CmiCallbackLock); - - for(CurrentEntry = CmiCallbackHead.Flink; - CurrentEntry != &CmiCallbackHead; - CurrentEntry = CurrentEntry->Flink) - { - PREGISTRY_CALLBACK CurrentCallback; - - CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); - if(!CurrentCallback->PendingDelete && - ExAcquireRundownProtection(&CurrentCallback->RundownRef)) - { - /* don't hold locks during the callbacks! */ - ExReleaseFastMutex(&CmiCallbackLock); - - Status = CurrentCallback->Function(CurrentCallback->Context, - (PVOID)Argument1, - Argument2); - - ExAcquireFastMutex(&CmiCallbackLock); - /* don't release the rundown protection before holding the callback lock - so the pointer to the next callback isn't cleared in case this callback - get's deleted */ - ExReleaseRundownProtection(&CurrentCallback->RundownRef); - if(!NT_SUCCESS(Status)) - { - /* one callback returned failure, don't call any more callbacks */ - break; - } - } - } - - ExReleaseFastMutex(&CmiCallbackLock); - - return Status; -} - - NTSTATUS STDCALL NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, @@ -2219,22 +2071,6 @@ Fail: return Status; } - -/* - * NOTE: - * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and - * KeyObjectAttributes->Name specifies the name of the key to load. - */ -NTSTATUS STDCALL -NtLoadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes, - IN POBJECT_ATTRIBUTES FileObjectAttributes) -{ - return NtLoadKey2 (KeyObjectAttributes, - FileObjectAttributes, - 0); -} - - /* * NOTE: * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and @@ -2357,52 +2193,6 @@ NtLoadKey2 (IN POBJECT_ATTRIBUTES KeyObjectAttributes, return Status; } - -NTSTATUS STDCALL -NtNotifyChangeKey (IN HANDLE KeyHandle, - IN HANDLE Event, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG CompletionFilter, - IN BOOLEAN WatchSubtree, - OUT PVOID Buffer, - IN ULONG Length, - IN BOOLEAN Asynchronous) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - -#if 0 -NTSTATUS STDCALL -NtNotifyChangeKey (IN HANDLE KeyHandle, - IN HANDLE Event, - IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, - IN PVOID ApcContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN ULONG CompletionFilter, - IN BOOLEAN WatchSubtree, - OUT PVOID Buffer, - IN ULONG Length, - IN BOOLEAN Asynchronous) -{ - return NtNotifyChangeMultipleKeys(KeyHandle, - 0, - NULL, - Event, - ApcRoutine, - ApcContext, - IoStatusBlock, - CompletionFilter, - WatchTree, - Buffer, - Length, - Asynchronous); -} - -#endif - NTSTATUS STDCALL NtQueryMultipleValueKey (IN HANDLE KeyHandle, IN OUT PKEY_VALUE_ENTRY ValueList, @@ -2542,269 +2332,6 @@ NtQueryMultipleValueKey (IN HANDLE KeyHandle, return Status; } - -NTSTATUS STDCALL -NtReplaceKey (IN POBJECT_ATTRIBUTES ObjectAttributes, - IN HANDLE Key, - IN POBJECT_ATTRIBUTES ReplacedObjectAttributes) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - - -NTSTATUS STDCALL -NtRestoreKey (IN HANDLE KeyHandle, - IN HANDLE FileHandle, - IN ULONG RestoreFlags) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); -} - - -NTSTATUS STDCALL -NtSaveKey (IN HANDLE KeyHandle, - IN HANDLE FileHandle) -{ - PEREGISTRY_HIVE TempHive; - PKEY_OBJECT KeyObject; - NTSTATUS Status; - - PAGED_CODE(); - - DPRINT ("NtSaveKey() called\n"); - -#if 0 - if (!SeSinglePrivilegeCheck (SeBackupPrivilege, ExGetPreviousMode ())) - return STATUS_PRIVILEGE_NOT_HELD; -#endif - - Status = ObReferenceObjectByHandle (KeyHandle, - 0, - CmiKeyType, - ExGetPreviousMode(), - (PVOID *)&KeyObject, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("ObReferenceObjectByHandle() failed (Status %lx)\n", Status); - return Status; - } - - /* Acquire hive lock exclucively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); - - /* Refuse to save a volatile key */ - if (KeyObject->KeyCell->Flags & REG_KEY_VOLATILE_CELL) - { - DPRINT1 ("Cannot save a volatile key\n"); - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - ObDereferenceObject (KeyObject); - return STATUS_ACCESS_DENIED; - } - - Status = CmiCreateTempHive(&TempHive); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("CmiCreateTempHive() failed (Status %lx)\n", Status); - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - ObDereferenceObject (KeyObject); - return(Status); - } - - Status = CmiCopyKey (TempHive, - NULL, - KeyObject->RegistryHive, - KeyObject->KeyCell); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("CmiCopyKey() failed (Status %lx)\n", Status); - CmiRemoveRegistryHive (TempHive); - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - ObDereferenceObject (KeyObject); - return(Status); - } - - Status = CmiSaveTempHive (TempHive, - FileHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("CmiSaveTempHive() failed (Status %lx)\n", Status); - } - - CmiRemoveRegistryHive (TempHive); - - /* Release hive lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - - ObDereferenceObject (KeyObject); - - DPRINT ("NtSaveKey() done\n"); - - return STATUS_SUCCESS; -} - -/* - * @unimplemented - */ -NTSTATUS -STDCALL -NtSaveKeyEx( - IN HANDLE KeyHandle, - IN HANDLE FileHandle, - IN ULONG Flags // REG_STANDARD_FORMAT, etc.. - ) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - - -NTSTATUS STDCALL -NtSetInformationKey (IN HANDLE KeyHandle, - IN KEY_SET_INFORMATION_CLASS KeyInformationClass, - IN PVOID KeyInformation, - IN ULONG KeyInformationLength) -{ - PKEY_OBJECT KeyObject; - NTSTATUS Status; - REG_SET_INFORMATION_KEY_INFORMATION SetInformationKeyInfo; - REG_POST_OPERATION_INFORMATION PostOperationInfo; - - PAGED_CODE(); - - /* Verify that the handle is valid and is a registry key */ - Status = ObReferenceObjectByHandle (KeyHandle, - KEY_SET_VALUE, - CmiKeyType, - ExGetPreviousMode(), - (PVOID *)&KeyObject, - NULL); - if (!NT_SUCCESS (Status)) - { - DPRINT ("ObReferenceObjectByHandle() failed with status %x\n", Status); - return Status; - } - - PostOperationInfo.Object = (PVOID)KeyObject; - SetInformationKeyInfo.Object = (PVOID)KeyObject; - SetInformationKeyInfo.KeySetInformationClass = KeyInformationClass; - SetInformationKeyInfo.KeySetInformation = KeyInformation; - SetInformationKeyInfo.KeySetInformationLength = KeyInformationLength; - - Status = CmiCallRegisteredCallbacks(RegNtPreSetInformationKey, &SetInformationKeyInfo); - if (!NT_SUCCESS(Status)) - { - PostOperationInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostSetInformationKey, &PostOperationInfo); - ObDereferenceObject (KeyObject); - return Status; - } - - if (KeyInformationClass != KeyWriteTimeInformation) - { - Status = STATUS_INVALID_INFO_CLASS; - } - - else if (KeyInformationLength != sizeof (KEY_WRITE_TIME_INFORMATION)) - { - Status = STATUS_INFO_LENGTH_MISMATCH; - } - else - { - /* Acquire hive lock */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); - - VERIFY_KEY_OBJECT(KeyObject); - - KeyObject->KeyCell->LastWriteTime.QuadPart = - ((PKEY_WRITE_TIME_INFORMATION)KeyInformation)->LastWriteTime.QuadPart; - - HvMarkCellDirty (&KeyObject->RegistryHive->Hive, - KeyObject->KeyCellOffset); - - /* Release hive lock */ - ExReleaseResourceLite(&CmiRegistryLock); - KeLeaveCriticalRegion(); - } - - PostOperationInfo.Status = Status; - CmiCallRegisteredCallbacks(RegNtPostSetInformationKey, &PostOperationInfo); - - ObDereferenceObject (KeyObject); - - if (NT_SUCCESS(Status)) - { - CmiSyncHives (); - } - - DPRINT ("NtSaveKey() done\n"); - - return STATUS_SUCCESS; -} - - -/* - * NOTE: - * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and - * KeyObjectAttributes->Name specifies the name of the key to unload. - */ -NTSTATUS STDCALL -NtUnloadKey (IN POBJECT_ATTRIBUTES KeyObjectAttributes) -{ - PEREGISTRY_HIVE RegistryHive; - NTSTATUS Status; - - PAGED_CODE(); - - DPRINT ("NtUnloadKey() called\n"); - -#if 0 - if (!SeSinglePrivilegeCheck (SeRestorePrivilege, ExGetPreviousMode ())) - return STATUS_PRIVILEGE_NOT_HELD; -#endif - - /* Acquire registry lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); - - Status = CmiDisconnectHive (KeyObjectAttributes, - &RegistryHive); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("CmiDisconnectHive() failed (Status %lx)\n", Status); - ExReleaseResourceLite (&CmiRegistryLock); - KeLeaveCriticalRegion(); - return Status; - } - - DPRINT ("RegistryHive %p\n", RegistryHive); - -#if 0 - /* Flush hive */ - if (!IsNoFileHive (RegistryHive)) - CmiFlushRegistryHive (RegistryHive); -#endif - - CmiRemoveRegistryHive (RegistryHive); - - /* Release registry lock */ - ExReleaseResourceLite (&CmiRegistryLock); - KeLeaveCriticalRegion(); - - DPRINT ("NtUnloadKey() done\n"); - - return STATUS_SUCCESS; -} - - NTSTATUS STDCALL NtInitializeRegistry (IN BOOLEAN SetUpBoot) { @@ -2842,6 +2369,14 @@ NtCompressKey(IN HANDLE Key) return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, + IN POBJECT_ATTRIBUTES FileObjectAttributes) +{ + return NtLoadKey2(KeyObjectAttributes, FileObjectAttributes, 0); +} + NTSTATUS NTAPI NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey, @@ -2892,6 +2427,33 @@ NtNotifyChangeMultipleKeys(IN HANDLE MasterKeyHandle, return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +NtNotifyChangeKey(IN HANDLE KeyHandle, + IN HANDLE Event, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN Asynchronous) +{ + return NtNotifyChangeMultipleKeys(KeyHandle, + 0, + NULL, + Event, + ApcRoutine, + ApcContext, + IoStatusBlock, + CompletionFilter, + WatchTree, + Buffer, + Length, + Asynchronous); +} + NTSTATUS NTAPI NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey, @@ -2912,6 +2474,45 @@ NtQueryOpenSubKeysEx(IN POBJECT_ATTRIBUTES TargetKey, return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +NtReplaceKey(IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE Key, + IN POBJECT_ATTRIBUTES ReplacedObjectAttributes) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtRestoreKey(IN HANDLE KeyHandle, + IN HANDLE FileHandle, + IN ULONG RestoreFlags) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtSaveKey(IN HANDLE KeyHandle, + IN HANDLE FileHandle) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtSaveKeyEx(IN HANDLE KeyHandle, + IN HANDLE FileHandle, + IN ULONG Flags) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS NTAPI NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle, @@ -2922,6 +2523,25 @@ NtSaveMergedKeys(IN HANDLE HighPrecedenceKeyHandle, return STATUS_NOT_IMPLEMENTED; } +NTSTATUS +NTAPI +NtSetInformationKey(IN HANDLE KeyHandle, + IN KEY_SET_INFORMATION_CLASS KeyInformationClass, + IN PVOID KeyInformation, + IN ULONG KeyInformationLength) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +} + NTSTATUS NTAPI NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey, diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index bb496a36196..e876b2dbce9 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -497,13 +497,6 @@ CmInitSystem1(VOID) BaseAddress = CmpRosGetHardwareHive(&Length); if (!CmImportHardwareHive(BaseAddress, Length, &HardwareHive)) { - /* Create dummy keys if no hardware hive was found */ - if (!CmImportHardwareHive (NULL, 0, &HardwareHive)) - { - /* Bugcheck */ - KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0); - } - /* Don't actually link anything below */ Allocate = TRUE; } @@ -687,108 +680,6 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes, return STATUS_SUCCESS; } - -NTSTATUS -CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes, - OUT PEREGISTRY_HIVE *RegistryHive) -{ - PKEY_OBJECT KeyObject; - PEREGISTRY_HIVE Hive; - HANDLE KeyHandle; - NTSTATUS Status = STATUS_OBJECT_NAME_NOT_FOUND; - PLIST_ENTRY CurrentEntry; - PKEY_OBJECT CurrentKey; - - DPRINT("CmiDisconnectHive() called\n"); - - *RegistryHive = NULL; - - Status = ObOpenObjectByName (KeyObjectAttributes, - CmiKeyType, - KernelMode, - NULL, - STANDARD_RIGHTS_REQUIRED, - NULL, - &KeyHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("ObOpenObjectByName() failed (Status %lx)\n", Status); - return Status; - } - - Status = ObReferenceObjectByHandle (KeyHandle, - STANDARD_RIGHTS_REQUIRED, - CmiKeyType, - KernelMode, - (PVOID*)&KeyObject, - NULL); - ZwClose (KeyHandle); - - if (!NT_SUCCESS(Status)) - { - DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status); - return Status; - } - DPRINT ("KeyObject %p Hive %p\n", KeyObject, KeyObject->RegistryHive); - - /* Acquire registry lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); - - Hive = KeyObject->RegistryHive; - - CurrentEntry = CmiKeyObjectListHead.Flink; - while (CurrentEntry != &CmiKeyObjectListHead) - { - CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry); - if (CurrentKey->RegistryHive == Hive && - 1 == ObGetObjectPointerCount(CurrentKey) && - !(CurrentKey->Flags & KO_MARKED_FOR_DELETE)) - { - ObDereferenceObject(CurrentKey); - CurrentEntry = CmiKeyObjectListHead.Flink; - } - else - { - CurrentEntry = CurrentEntry->Flink; - } - } - - /* FN1 */ - ObDereferenceObject (KeyObject); - - if (ObGetObjectHandleCount (KeyObject) != 0 || - ObGetObjectPointerCount (KeyObject) != 2) - { - DPRINT1 ("Hive is still in use (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject)); - ObDereferenceObject (KeyObject); - - /* Release registry lock */ - ExReleaseResourceLite (&CmiRegistryLock); - KeLeaveCriticalRegion(); - - return STATUS_UNSUCCESSFUL; - } - - /* Dereference KeyObject twice to delete it */ - ObDereferenceObject (KeyObject); - ObDereferenceObject (KeyObject); - - *RegistryHive = Hive; - - /* Release registry lock */ - ExReleaseResourceLite (&CmiRegistryLock); - KeLeaveCriticalRegion(); - - /* Release reference above */ - ObDereferenceObject (KeyObject); - - DPRINT ("CmiDisconnectHive() done\n"); - - return Status; -} - - static NTSTATUS CmiInitControlSetLink (VOID) { diff --git a/reactos/ntoskrnl/config/cmhook.c b/reactos/ntoskrnl/config/cmhook.c new file mode 100644 index 00000000000..24b699f9ca9 --- /dev/null +++ b/reactos/ntoskrnl/config/cmhook.c @@ -0,0 +1,173 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/config/cmhook.c + * PURPOSE: Configuration Manager - Registry Notifications/Callbacks + * PROGRAMMERS: Thomas Weidenmueller (w3seek@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "ntoskrnl.h" +#include "cm.h" +#define NDEBUG +#include "debug.h" + +/* GLOBALS *******************************************************************/ + +LIST_ENTRY CmiCallbackHead; +FAST_MUTEX CmiCallbackLock; + +typedef struct _REGISTRY_CALLBACK +{ + LIST_ENTRY ListEntry; + EX_RUNDOWN_REF RundownRef; + PEX_CALLBACK_FUNCTION Function; + PVOID Context; + LARGE_INTEGER Cookie; + BOOLEAN PendingDelete; +} REGISTRY_CALLBACK, *PREGISTRY_CALLBACK; + +/* PRIVATE FUNCTIONS *********************************************************/ + +NTSTATUS +CmiCallRegisteredCallbacks(IN REG_NOTIFY_CLASS Argument1, + IN PVOID Argument2) +{ + PLIST_ENTRY CurrentEntry; + NTSTATUS Status = STATUS_SUCCESS; + PREGISTRY_CALLBACK CurrentCallback; + PAGED_CODE(); + + ExAcquireFastMutex(&CmiCallbackLock); + + for (CurrentEntry = CmiCallbackHead.Flink; + CurrentEntry != &CmiCallbackHead; + CurrentEntry = CurrentEntry->Flink) + { + CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); + if (!CurrentCallback->PendingDelete && + ExAcquireRundownProtection(&CurrentCallback->RundownRef)) + { + /* don't hold locks during the callbacks! */ + ExReleaseFastMutex(&CmiCallbackLock); + + Status = CurrentCallback->Function(CurrentCallback->Context, + (PVOID)Argument1, + Argument2); + + ExAcquireFastMutex(&CmiCallbackLock); + + /* don't release the rundown protection before holding the callback lock + so the pointer to the next callback isn't cleared in case this callback + get's deleted */ + ExReleaseRundownProtection(&CurrentCallback->RundownRef); + if(!NT_SUCCESS(Status)) + { + /* one callback returned failure, don't call any more callbacks */ + break; + } + } + } + + ExReleaseFastMutex(&CmiCallbackLock); + + return Status; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function, + IN PVOID Context, + IN OUT PLARGE_INTEGER Cookie) +{ + PREGISTRY_CALLBACK Callback; + PAGED_CODE(); + ASSERT(Function && Cookie); + + Callback = ExAllocatePoolWithTag(PagedPool, + sizeof(REGISTRY_CALLBACK), + TAG('C', 'M', 'c', 'b')); + if (Callback != NULL) + { + /* initialize the callback */ + ExInitializeRundownProtection(&Callback->RundownRef); + Callback->Function = Function; + Callback->Context = Context; + Callback->PendingDelete = FALSE; + + /* add it to the callback list and receive a cookie for the callback */ + ExAcquireFastMutex(&CmiCallbackLock); + + /* FIXME - to receive a unique cookie we'll just return the pointer to the + callback object */ + Callback->Cookie.QuadPart = (ULONG_PTR)Callback; + InsertTailList(&CmiCallbackHead, &Callback->ListEntry); + + ExReleaseFastMutex(&CmiCallbackLock); + + *Cookie = Callback->Cookie; + return STATUS_SUCCESS; + } + + return STATUS_INSUFFICIENT_RESOURCES; +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +CmUnRegisterCallback(IN LARGE_INTEGER Cookie) +{ + PLIST_ENTRY CurrentEntry; + PREGISTRY_CALLBACK CurrentCallback; + PAGED_CODE(); + + ExAcquireFastMutex(&CmiCallbackLock); + + for (CurrentEntry = CmiCallbackHead.Flink; + CurrentEntry != &CmiCallbackHead; + CurrentEntry = CurrentEntry->Flink) + { + CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry); + if (CurrentCallback->Cookie.QuadPart == Cookie.QuadPart) + { + if (!CurrentCallback->PendingDelete) + { + /* found the callback, don't unlink it from the list yet so we don't screw + the calling loop */ + CurrentCallback->PendingDelete = TRUE; + ExReleaseFastMutex(&CmiCallbackLock); + + /* if the callback is currently executing, wait until it finished */ + ExWaitForRundownProtectionRelease(&CurrentCallback->RundownRef); + + /* time to unlink it. It's now safe because every attempt to acquire a + runtime protection on this callback will fail */ + ExAcquireFastMutex(&CmiCallbackLock); + RemoveEntryList(&CurrentCallback->ListEntry); + ExReleaseFastMutex(&CmiCallbackLock); + + /* free the callback */ + ExFreePool(CurrentCallback); + return STATUS_SUCCESS; + } + else + { + /* pending delete, pretend like it already is deleted */ + ExReleaseFastMutex(&CmiCallbackLock); + return STATUS_UNSUCCESSFUL; + } + } + } + + ExReleaseFastMutex(&CmiCallbackLock); + + return STATUS_UNSUCCESSFUL; +} diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 78c12cdd26e..ef592d7c616 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -88,6 +88,7 @@ cmcontrl.c cmdata.c cmindex.c + cmhook.c cmmapvw.c cmname.c cmparse.c