mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 01:42:30 +00:00
- Get rid of ReactOS Hive Flags.
- Get rid of some cruft from headers. - Switch to new lazy flush code and get rid of older one. - Update NtFlushKey to use CmFlushKey. svn path=/trunk/; revision=30207
This commit is contained in:
parent
0af0de852b
commit
6492c8da81
|
@ -37,24 +37,6 @@
|
|||
#define REG_SAM_FILE_NAME L"\\sam"
|
||||
#define REG_SEC_FILE_NAME L"\\security"
|
||||
|
||||
/* When set, the hive is not backed by a file.
|
||||
Therefore, it can not be flushed to disk. */
|
||||
#define HIVE_NO_FILE 0x00000002
|
||||
|
||||
/* When set, a modified (dirty) hive is not synchronized automatically.
|
||||
Explicit synchronization (save/flush) works. */
|
||||
#define HIVE_NO_SYNCH 0x00000004
|
||||
|
||||
#define IsNoFileHive(Hive) ((Hive)->Flags & HIVE_NO_FILE)
|
||||
#define IsNoSynchHive(Hive) ((Hive)->Flags & HIVE_NO_SYNCH)
|
||||
|
||||
|
||||
/* KEY_OBJECT.Flags */
|
||||
|
||||
/* When set, the key is scheduled for deletion, and all
|
||||
attempts to access the key must not succeed */
|
||||
#define KO_MARKED_FOR_DELETE 0x00000001
|
||||
|
||||
/* Bits 31-22 (top 10 bits) of the cell index is the directory index */
|
||||
#define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
|
||||
/* Bits 21-12 (middle 10 bits) of the cell index is the table index */
|
||||
|
@ -105,29 +87,11 @@ VOID
|
|||
CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
|
||||
IN PKEY_OBJECT NewKey);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyList(IN PKEY_OBJECT Parent,
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN ULONG Attributes,
|
||||
PKEY_OBJECT* ReturnedObject);
|
||||
|
||||
NTSTATUS
|
||||
CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||
PCUNICODE_STRING FileName,
|
||||
ULONG Flags);
|
||||
|
||||
NTSTATUS
|
||||
CmiFlushRegistryHive(PCMHIVE RegistryHive);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanForSubKey(IN PCMHIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
OUT PCM_KEY_NODE *SubKeyCell,
|
||||
OUT HCELL_INDEX *BlockOffset,
|
||||
IN PCUNICODE_STRING KeyName,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN ULONG Attributes);
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
|
@ -135,6 +99,9 @@ CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
|||
OUT PCM_KEY_VALUE *ValueCell,
|
||||
OUT HCELL_INDEX *VBOffset);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CmpLazyFlush(VOID);
|
||||
|
||||
NTSTATUS
|
||||
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||
|
@ -143,9 +110,6 @@ CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
NTSTATUS
|
||||
CmiInitHives(BOOLEAN SetupBoot);
|
||||
|
||||
VOID
|
||||
CmiSyncHives(VOID);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmFindObject(
|
||||
|
|
|
@ -389,7 +389,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
|||
PostCreateKeyInfo.Status = Status;
|
||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||
|
||||
CmiSyncHives();
|
||||
CmpLazyFlush();
|
||||
|
||||
LocalDisposition = REG_CREATED_NEW_KEY;
|
||||
|
||||
|
@ -422,59 +422,6 @@ Cleanup:
|
|||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtFlushKey(IN HANDLE KeyHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PKEY_OBJECT KeyObject;
|
||||
PCMHIVE RegistryHive;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtFlushKey (KeyHandle %lx) called\n", KeyHandle);
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
/* Verify that the handle is valid and is a registry key */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
0,
|
||||
CmpKeyObjectType,
|
||||
PreviousMode,
|
||||
(PVOID *)&KeyObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
VERIFY_KEY_OBJECT(KeyObject);
|
||||
|
||||
RegistryHive = (PCMHIVE)KeyObject->KeyControlBlock->KeyHive;
|
||||
|
||||
/* Acquire hive lock */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
|
||||
if (IsNoFileHive(RegistryHive))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Flush non-volatile hive */
|
||||
Status = CmiFlushRegistryHive(RegistryHive);
|
||||
}
|
||||
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
ObDereferenceObject(KeyObject);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtOpenKey(OUT PHANDLE KeyHandle,
|
||||
|
@ -687,6 +634,7 @@ NtInitializeRegistry (IN USHORT Flag)
|
|||
|
||||
Status = CmiInitHives (Flag);
|
||||
|
||||
CmpCmdInit(Flag);
|
||||
CmiRegistryInitialized = TRUE;
|
||||
|
||||
return Status;
|
||||
|
|
|
@ -58,49 +58,6 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
|||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
CmCloseHiveFiles(PCMHIVE RegistryHive)
|
||||
{
|
||||
ZwClose(RegistryHive->FileHandles[HFILE_TYPE_PRIMARY]);
|
||||
ZwClose(RegistryHive->FileHandles[HFILE_TYPE_LOG]);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiFlushRegistryHive(PCMHIVE RegistryHive)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
NTSTATUS Status;
|
||||
ULONG Disposition;
|
||||
|
||||
ASSERT(!RegistryHive->Hive.HiveFlags & HIVE_VOLATILE);
|
||||
|
||||
if (RtlFindSetBits(&RegistryHive->Hive.DirtyVector, 1, 0) == ~0)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
Status = CmpOpenHiveFiles(&RegistryHive->FileFullPath,
|
||||
L".LOG",
|
||||
&RegistryHive->FileHandles[HFILE_TYPE_PRIMARY],
|
||||
&RegistryHive->FileHandles[HFILE_TYPE_LOG],
|
||||
&Disposition,
|
||||
&Disposition,
|
||||
FALSE,
|
||||
FALSE,
|
||||
TRUE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
Success = HvSyncHive(&RegistryHive->Hive);
|
||||
|
||||
CmCloseHiveFiles(RegistryHive);
|
||||
|
||||
return Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
||||
IN PCM_KEY_NODE KeyCell,
|
||||
|
|
|
@ -37,18 +37,6 @@ ERESOURCE CmpRegistryLock;
|
|||
LIST_ENTRY CmiKeyObjectListHead;
|
||||
LIST_ENTRY CmiConnectedHiveList;
|
||||
|
||||
volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
|
||||
volatile BOOLEAN CmiHiveSyncPending = FALSE;
|
||||
KDPC CmiHiveSyncDpc;
|
||||
KTIMER CmiHiveSyncTimer;
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2);
|
||||
|
||||
extern LIST_ENTRY CmiCallbackHead;
|
||||
extern FAST_MUTEX CmiCallbackLock;
|
||||
|
||||
|
@ -520,15 +508,6 @@ CmiInitHives(BOOLEAN SetupBoot)
|
|||
return(Status);
|
||||
}
|
||||
|
||||
//CmiCheckRegistry(TRUE);
|
||||
|
||||
/* Start automatic hive synchronization */
|
||||
KeInitializeDpc(&CmiHiveSyncDpc,
|
||||
CmiHiveSyncDpcRoutine,
|
||||
NULL);
|
||||
KeInitializeTimer(&CmiHiveSyncTimer);
|
||||
CmiHiveSyncEnabled = TRUE;
|
||||
|
||||
DPRINT("CmiInitHives() done\n");
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
|
@ -538,128 +517,7 @@ VOID
|
|||
NTAPI
|
||||
CmShutdownRegistry(VOID)
|
||||
{
|
||||
PCMHIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
|
||||
DPRINT("CmShutdownRegistry() called\n");
|
||||
|
||||
/* Stop automatic hive synchronization */
|
||||
CmiHiveSyncEnabled = FALSE;
|
||||
|
||||
/* Cancel pending hive synchronization */
|
||||
if (CmiHiveSyncPending == TRUE)
|
||||
{
|
||||
KeCancelTimer(&CmiHiveSyncTimer);
|
||||
CmiHiveSyncPending = FALSE;
|
||||
}
|
||||
|
||||
/* Lock the hive list */
|
||||
ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
|
||||
|
||||
Entry = CmpHiveListHead.Flink;
|
||||
while (Entry != &CmpHiveListHead)
|
||||
{
|
||||
Hive = CONTAINING_RECORD(Entry, CMHIVE, HiveList);
|
||||
|
||||
if (!(IsNoFileHive(Hive) ||
|
||||
IsNoSynchHive(Hive) ||
|
||||
(Hive->Hive.HiveFlags & HIVE_VOLATILE)))
|
||||
{
|
||||
/* Flush non-volatile hive */
|
||||
CmiFlushRegistryHive(Hive);
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
ExReleasePushLock(&CmpHiveListHeadLock);
|
||||
|
||||
DPRINT("CmShutdownRegistry() done\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CmiHiveSyncRoutine(PVOID DeferredContext)
|
||||
{
|
||||
PCMHIVE Hive;
|
||||
PLIST_ENTRY Entry;
|
||||
|
||||
DPRINT("CmiHiveSyncRoutine() called\n");
|
||||
|
||||
CmiHiveSyncPending = FALSE;
|
||||
|
||||
/* Lock the hive list */
|
||||
ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
|
||||
|
||||
Entry = CmpHiveListHead.Flink;
|
||||
while (Entry != &CmpHiveListHead)
|
||||
{
|
||||
Hive = CONTAINING_RECORD(Entry, CMHIVE, HiveList);
|
||||
|
||||
if (!(IsNoFileHive(Hive) ||
|
||||
IsNoSynchHive(Hive) ||
|
||||
(Hive->Hive.HiveFlags & HIVE_VOLATILE)))
|
||||
{
|
||||
/* Flush non-volatile hive */
|
||||
CmiFlushRegistryHive(Hive);
|
||||
}
|
||||
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
ExReleasePushLock(&CmpHiveListHeadLock);
|
||||
|
||||
DPRINT("DeferredContext 0x%p\n", DeferredContext);
|
||||
ExFreePool(DeferredContext);
|
||||
|
||||
DPRINT("CmiHiveSyncRoutine() done\n");
|
||||
}
|
||||
|
||||
static VOID
|
||||
NTAPI
|
||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PWORK_QUEUE_ITEM WorkQueueItem;
|
||||
|
||||
WorkQueueItem = ExAllocatePool(NonPagedPool,
|
||||
sizeof(WORK_QUEUE_ITEM));
|
||||
if (WorkQueueItem == NULL)
|
||||
{
|
||||
DPRINT1("Failed to allocate work item\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ExInitializeWorkItem(WorkQueueItem,
|
||||
CmiHiveSyncRoutine,
|
||||
WorkQueueItem);
|
||||
|
||||
DPRINT("DeferredContext 0x%p\n", WorkQueueItem);
|
||||
ExQueueWorkItem(WorkQueueItem,
|
||||
CriticalWorkQueue);
|
||||
}
|
||||
|
||||
VOID
|
||||
CmiSyncHives(VOID)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
DPRINT("CmiSyncHives() called\n");
|
||||
|
||||
if (CmiHiveSyncEnabled == FALSE ||
|
||||
CmiHiveSyncPending == TRUE)
|
||||
return;
|
||||
|
||||
CmiHiveSyncPending = TRUE;
|
||||
|
||||
Timeout.QuadPart = (LONGLONG)-50000000;
|
||||
KeSetTimer(&CmiHiveSyncTimer,
|
||||
Timeout,
|
||||
&CmiHiveSyncDpc);
|
||||
CmShutdownSystem();
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -340,6 +340,64 @@ Next:
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Preconditions: Must be called with CmpRegistryLock held. */
|
||||
NTSTATUS
|
||||
CmiScanKeyList(PKEY_OBJECT Parent,
|
||||
PCUNICODE_STRING KeyName,
|
||||
ULONG Attributes,
|
||||
PKEY_OBJECT* ReturnedObject)
|
||||
{
|
||||
PKEY_OBJECT CurKey = NULL;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
|
||||
KeyName, &Parent->Name);
|
||||
|
||||
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
|
||||
/* (a binary search) */
|
||||
for (Index=0; Index < Parent->SubKeyCounts; Index++)
|
||||
{
|
||||
CurKey = Parent->SubKeys[Index];
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
|
||||
if ((KeyName->Length == CurKey->Name.Length)
|
||||
&& (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((KeyName->Length == CurKey->Name.Length)
|
||||
&& (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Index < Parent->SubKeyCounts)
|
||||
{
|
||||
if (CurKey->KeyControlBlock->Delete)
|
||||
{
|
||||
CHECKPOINT;
|
||||
*ReturnedObject = NULL;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
ObReferenceObject(CurKey);
|
||||
*ReturnedObject = CurKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ReturnedObject = NULL;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpParseKey(IN PVOID ParsedObject,
|
||||
|
@ -772,61 +830,6 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
|
|||
//NewKey->ParentKey = ParentKey;
|
||||
}
|
||||
|
||||
/* Preconditions: Must be called with CmpRegistryLock held. */
|
||||
NTSTATUS
|
||||
CmiScanKeyList(PKEY_OBJECT Parent,
|
||||
PCUNICODE_STRING KeyName,
|
||||
ULONG Attributes,
|
||||
PKEY_OBJECT* ReturnedObject)
|
||||
{
|
||||
PKEY_OBJECT CurKey = NULL;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
|
||||
KeyName, &Parent->Name);
|
||||
|
||||
/* FIXME: if list maintained in alphabetic order, use dichotomic search */
|
||||
/* (a binary search) */
|
||||
for (Index=0; Index < Parent->SubKeyCounts; Index++)
|
||||
{
|
||||
CurKey = Parent->SubKeys[Index];
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
DPRINT("Comparing %wZ and %wZ\n", KeyName, &CurKey->Name);
|
||||
if ((KeyName->Length == CurKey->Name.Length)
|
||||
&& (_wcsicmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((KeyName->Length == CurKey->Name.Length)
|
||||
&& (wcscmp(KeyName->Buffer, CurKey->Name.Buffer) == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Index < Parent->SubKeyCounts)
|
||||
{
|
||||
if (CurKey->KeyControlBlock->Delete)
|
||||
{
|
||||
CHECKPOINT;
|
||||
*ReturnedObject = NULL;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
ObReferenceObject(CurKey);
|
||||
*ReturnedObject = CurKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ReturnedObject = NULL;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
CmiGetLinkTarget(PCMHIVE RegistryHive,
|
||||
PCM_KEY_NODE KeyCell,
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -373,7 +373,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
|
|||
ObDereferenceObject(KeyObject);
|
||||
|
||||
/* Synchronize the hives and return */
|
||||
CmiSyncHives();
|
||||
CmpLazyFlush();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -421,7 +421,49 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
|
|||
|
||||
/* Dereference the key body and synchronize the hives */
|
||||
ObDereferenceObject(KeyObject);
|
||||
CmiSyncHives();
|
||||
CmpLazyFlush();
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtFlushKey(IN HANDLE KeyHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PKEY_OBJECT KeyObject;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the key object */
|
||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||
0,
|
||||
CmpKeyObjectType,
|
||||
ExGetPreviousMode(),
|
||||
(PVOID*)&KeyObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Lock the registry */
|
||||
KeEnterCriticalRegion();
|
||||
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
|
||||
|
||||
/* Make sure KCB isn't deleted */
|
||||
if (KeyObject->KeyControlBlock->Delete)
|
||||
{
|
||||
/* Fail */
|
||||
Status = STATUS_KEY_DELETED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the internal API */
|
||||
Status = CmFlushKey(KeyObject->KeyControlBlock, FALSE);
|
||||
}
|
||||
|
||||
/* Release the lock */
|
||||
ExReleaseResourceLite(&CmpRegistryLock);
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
/* Dereference the object and return status */
|
||||
ObDereferenceObject(KeyObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue