Author: ion
Date: Thu May 10 13:14:15 2007
New Revision: 26671
URL:
http://svn.reactos.org/svn/reactos?rev=26671&view=rev
Log:
- Remove/deprecate some certain chunks of Cm which are not critical to booting and not
even to applications (such as NtSaveKey, which didn't even have NtRestoreKey) and mark
them as unimplemented functions.
- This doesn't do much but clean up some of our code to make it easier to see what the
critical parts are and reduce bug surface exposure.
- Move and slightly reformat (without touching any of the actual code) registry
callback/notification code to cmhook.c.
Added:
trunk/reactos/ntoskrnl/config/cmhook.c
Modified:
trunk/reactos/ntoskrnl/cm/import.c
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/registry.c
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: trunk/reactos/ntoskrnl/cm/import.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/import.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/import.c (original)
+++ trunk/reactos/ntoskrnl/cm/import.c Thu May 10 13:14:15 2007
@@ -91,20 +91,9 @@
{
*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 @@
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;
}
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Thu May 10 13:14:15 2007
@@ -29,9 +29,6 @@
static BOOLEAN CmiRegistryInitialized = FALSE;
-LIST_ENTRY CmiCallbackHead;
-FAST_MUTEX CmiCallbackLock;
-
/* FUNCTIONS ****************************************************************/
NTSTATUS
@@ -130,151 +127,6 @@
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,
@@ -2219,22 +2071,6 @@
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 @@
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 @@
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)
{
@@ -2840,6 +2367,14 @@
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+NTAPI
+NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN POBJECT_ATTRIBUTES FileObjectAttributes)
+{
+ return NtLoadKey2(KeyObjectAttributes, FileObjectAttributes, 0);
}
NTSTATUS
@@ -2894,6 +2429,33 @@
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,
IN ULONG HandleCount)
{
@@ -2914,9 +2476,67 @@
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,
IN HANDLE LowPrecedenceKeyHandle,
IN HANDLE FileHandle)
+{
+ UNIMPLEMENTED;
+ 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;
Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Thu May 10 13:14:15 2007
@@ -497,13 +497,6 @@
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 @@
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)
{
Added: trunk/reactos/ntoskrnl/config/cmhook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmhook.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmhook.c (added)
+++ trunk/reactos/ntoskrnl/config/cmhook.c Thu May 10 13:14:15 2007
@@ -1,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(a)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;
+}
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Thu May 10 13:14:15 2007
@@ -88,6 +88,7 @@
<file>cmcontrl.c</file>
<file>cmdata.c</file>
<file>cmindex.c</file>
+ <file>cmhook.c</file>
<file>cmmapvw.c</file>
<file>cmname.c</file>
<file>cmparse.c</file>