mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 00:55:48 +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
8 changed files with 2685 additions and 2882 deletions
|
@ -37,24 +37,6 @@
|
||||||
#define REG_SAM_FILE_NAME L"\\sam"
|
#define REG_SAM_FILE_NAME L"\\sam"
|
||||||
#define REG_SEC_FILE_NAME L"\\security"
|
#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 */
|
/* Bits 31-22 (top 10 bits) of the cell index is the directory index */
|
||||||
#define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
|
#define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
|
||||||
/* Bits 21-12 (middle 10 bits) of the cell index is the table index */
|
/* Bits 21-12 (middle 10 bits) of the cell index is the table index */
|
||||||
|
@ -105,29 +87,11 @@ VOID
|
||||||
CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
|
CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
|
||||||
IN PKEY_OBJECT NewKey);
|
IN PKEY_OBJECT NewKey);
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
CmiScanKeyList(IN PKEY_OBJECT Parent,
|
|
||||||
IN PCUNICODE_STRING KeyName,
|
|
||||||
IN ULONG Attributes,
|
|
||||||
PKEY_OBJECT* ReturnedObject);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
PCUNICODE_STRING FileName,
|
PCUNICODE_STRING FileName,
|
||||||
ULONG Flags);
|
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
|
NTSTATUS
|
||||||
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
||||||
IN PCM_KEY_NODE KeyCell,
|
IN PCM_KEY_NODE KeyCell,
|
||||||
|
@ -135,6 +99,9 @@ CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
||||||
OUT PCM_KEY_VALUE *ValueCell,
|
OUT PCM_KEY_VALUE *ValueCell,
|
||||||
OUT HCELL_INDEX *VBOffset);
|
OUT HCELL_INDEX *VBOffset);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
CmpLazyFlush(VOID);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
|
@ -143,9 +110,6 @@ CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiInitHives(BOOLEAN SetupBoot);
|
CmiInitHives(BOOLEAN SetupBoot);
|
||||||
|
|
||||||
VOID
|
|
||||||
CmiSyncHives(VOID);
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CmFindObject(
|
CmFindObject(
|
||||||
|
|
|
@ -389,7 +389,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
PostCreateKeyInfo.Status = Status;
|
PostCreateKeyInfo.Status = Status;
|
||||||
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
|
||||||
|
|
||||||
CmiSyncHives();
|
CmpLazyFlush();
|
||||||
|
|
||||||
LocalDisposition = REG_CREATED_NEW_KEY;
|
LocalDisposition = REG_CREATED_NEW_KEY;
|
||||||
|
|
||||||
|
@ -422,59 +422,6 @@ Cleanup:
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtOpenKey(OUT PHANDLE KeyHandle,
|
NtOpenKey(OUT PHANDLE KeyHandle,
|
||||||
|
@ -687,6 +634,7 @@ NtInitializeRegistry (IN USHORT Flag)
|
||||||
|
|
||||||
Status = CmiInitHives (Flag);
|
Status = CmiInitHives (Flag);
|
||||||
|
|
||||||
|
CmpCmdInit(Flag);
|
||||||
CmiRegistryInitialized = TRUE;
|
CmiRegistryInitialized = TRUE;
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -58,49 +58,6 @@ CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
CmiScanKeyForValue(IN PCMHIVE RegistryHive,
|
||||||
IN PCM_KEY_NODE KeyCell,
|
IN PCM_KEY_NODE KeyCell,
|
||||||
|
|
|
@ -37,18 +37,6 @@ ERESOURCE CmpRegistryLock;
|
||||||
LIST_ENTRY CmiKeyObjectListHead;
|
LIST_ENTRY CmiKeyObjectListHead;
|
||||||
LIST_ENTRY CmiConnectedHiveList;
|
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 LIST_ENTRY CmiCallbackHead;
|
||||||
extern FAST_MUTEX CmiCallbackLock;
|
extern FAST_MUTEX CmiCallbackLock;
|
||||||
|
|
||||||
|
@ -520,15 +508,6 @@ CmiInitHives(BOOLEAN SetupBoot)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
//CmiCheckRegistry(TRUE);
|
|
||||||
|
|
||||||
/* Start automatic hive synchronization */
|
|
||||||
KeInitializeDpc(&CmiHiveSyncDpc,
|
|
||||||
CmiHiveSyncDpcRoutine,
|
|
||||||
NULL);
|
|
||||||
KeInitializeTimer(&CmiHiveSyncTimer);
|
|
||||||
CmiHiveSyncEnabled = TRUE;
|
|
||||||
|
|
||||||
DPRINT("CmiInitHives() done\n");
|
DPRINT("CmiInitHives() done\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -538,128 +517,7 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CmShutdownRegistry(VOID)
|
CmShutdownRegistry(VOID)
|
||||||
{
|
{
|
||||||
PCMHIVE Hive;
|
CmShutdownSystem();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -340,6 +340,64 @@ Next:
|
||||||
return STATUS_SUCCESS;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CmpParseKey(IN PVOID ParsedObject,
|
CmpParseKey(IN PVOID ParsedObject,
|
||||||
|
@ -772,61 +830,6 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
|
||||||
//NewKey->ParentKey = 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
|
static NTSTATUS
|
||||||
CmiGetLinkTarget(PCMHIVE RegistryHive,
|
CmiGetLinkTarget(PCMHIVE RegistryHive,
|
||||||
PCM_KEY_NODE KeyCell,
|
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);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
/* Synchronize the hives and return */
|
/* Synchronize the hives and return */
|
||||||
CmiSyncHives();
|
CmpLazyFlush();
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,7 +421,49 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
|
||||||
|
|
||||||
/* Dereference the key body and synchronize the hives */
|
/* Dereference the key body and synchronize the hives */
|
||||||
ObDereferenceObject(KeyObject);
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue