- 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:
Aleksey Bragin 2007-11-05 22:54:47 +00:00
parent 0af0de852b
commit 6492c8da81
8 changed files with 2685 additions and 2882 deletions

View file

@ -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(

View file

@ -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;

View file

@ -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,

View file

@ -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 */

View file

@ -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

View file

@ -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;
}