mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 07:46:29 +00:00
[NTOSKRNL]
Implement NtQueryOpenSubKeys. svn path=/trunk/; revision=48902
This commit is contained in:
parent
c23c9c81ca
commit
db53bf24cb
3 changed files with 177 additions and 2 deletions
|
@ -4,6 +4,7 @@
|
||||||
* FILE: ntoskrnl/config/cmapi.c
|
* FILE: ntoskrnl/config/cmapi.c
|
||||||
* PURPOSE: Configuration Manager - Internal Registry APIs
|
* PURPOSE: Configuration Manager - Internal Registry APIs
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
* Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -1814,3 +1815,86 @@ CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
CmCountOpenSubKeys(IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
|
IN BOOLEAN RemoveEmptyCacheEntries)
|
||||||
|
{
|
||||||
|
PCM_KEY_HASH Entry;
|
||||||
|
PCM_KEY_CONTROL_BLOCK CachedKcb;
|
||||||
|
PCM_KEY_CONTROL_BLOCK ParentKcb;
|
||||||
|
USHORT ParentKeyCount;
|
||||||
|
USHORT j;
|
||||||
|
ULONG i;
|
||||||
|
ULONG SubKeys = 0;
|
||||||
|
|
||||||
|
DPRINT("CmCountOpenSubKeys() called\n");
|
||||||
|
|
||||||
|
/* The root key is the only referenced key. There are no refereced sub keys. */
|
||||||
|
if (RootKcb->RefCount == 1)
|
||||||
|
{
|
||||||
|
DPRINT("open sub keys: 0\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enumerate all hash lists */
|
||||||
|
for (i = 0; i < CmpHashTableSize; i++)
|
||||||
|
{
|
||||||
|
/* Get the first cache entry */
|
||||||
|
Entry = CmpCacheTable[i].Entry;
|
||||||
|
|
||||||
|
/* Enumerate all cache entries */
|
||||||
|
while (Entry)
|
||||||
|
{
|
||||||
|
/* Get the KCB of the current cache entry */
|
||||||
|
CachedKcb = CONTAINING_RECORD(Entry, CM_KEY_CONTROL_BLOCK, KeyHash);
|
||||||
|
|
||||||
|
/* Check keys only that are subkeys to our root key */
|
||||||
|
if (CachedKcb->TotalLevels > RootKcb->TotalLevels)
|
||||||
|
{
|
||||||
|
/* Calculate the number of parent keys to the root key */
|
||||||
|
ParentKeyCount = CachedKcb->TotalLevels - RootKcb->TotalLevels;
|
||||||
|
|
||||||
|
/* Find a parent key that could be the root key */
|
||||||
|
ParentKcb = CachedKcb;
|
||||||
|
for (j = 0; j < ParentKeyCount; j++)
|
||||||
|
{
|
||||||
|
ParentKcb = ParentKcb->ParentKcb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether the parent is the root key */
|
||||||
|
if (ParentKcb == RootKcb)
|
||||||
|
{
|
||||||
|
DPRINT("Found a sub key \n");
|
||||||
|
DPRINT("RefCount = %u\n", CachedKcb->RefCount);
|
||||||
|
|
||||||
|
if (CachedKcb->RefCount > 0)
|
||||||
|
{
|
||||||
|
/* Count the current hash entry if it is in use */
|
||||||
|
SubKeys++;
|
||||||
|
}
|
||||||
|
else if ((CachedKcb->RefCount == 0) && (RemoveEmptyCacheEntries == TRUE))
|
||||||
|
{
|
||||||
|
/* Remove the current key from the delayed close list */
|
||||||
|
CmpRemoveFromDelayedClose(CachedKcb);
|
||||||
|
|
||||||
|
/* Remove the current cache entry */
|
||||||
|
CmpCleanUpKcbCacheWithLock(CachedKcb, TRUE);
|
||||||
|
|
||||||
|
/* Restart, because the hash list has changed */
|
||||||
|
Entry = CmpCacheTable[i].Entry;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the next cache entry */
|
||||||
|
Entry = Entry->NextHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("open sub keys: %u\n", SubKeys);
|
||||||
|
|
||||||
|
return SubKeys;
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* FILE: ntoskrnl/config/cmapi.c
|
* FILE: ntoskrnl/config/cmapi.c
|
||||||
* PURPOSE: Configuration Manager - Internal Registry APIs
|
* PURPOSE: Configuration Manager - Internal Registry APIs
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
|
* Eric Kohl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -1015,8 +1016,91 @@ NTAPI
|
||||||
NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey,
|
NtQueryOpenSubKeys(IN POBJECT_ATTRIBUTES TargetKey,
|
||||||
OUT PULONG HandleCount)
|
OUT PULONG HandleCount)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
PCM_KEY_BODY KeyBody = NULL;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("NtQueryOpenSubKeys()\n");
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Get the processor mode */
|
||||||
|
PreviousMode = KeGetPreviousMode();
|
||||||
|
|
||||||
|
if (PreviousMode != KernelMode)
|
||||||
|
{
|
||||||
|
/* Prepare to probe parameters */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Probe target key */
|
||||||
|
ProbeForRead(TargetKey,
|
||||||
|
sizeof(OBJECT_ATTRIBUTES),
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
/* Probe handle count */
|
||||||
|
ProbeForWriteUlong(HandleCount);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Return the exception code */
|
||||||
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a handle to the key */
|
||||||
|
Status = ObOpenObjectByName(TargetKey,
|
||||||
|
CmpKeyObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
NULL,
|
||||||
|
KEY_READ,
|
||||||
|
NULL,
|
||||||
|
&KeyHandle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Reference the key object */
|
||||||
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
|
KEY_READ,
|
||||||
|
CmpKeyObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID *)&KeyBody,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Close the handle */
|
||||||
|
NtClose(KeyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fail, if the key object could not be referenced */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* Lock the registry exclusively */
|
||||||
|
CmpLockRegistryExclusive();
|
||||||
|
|
||||||
|
/* Fail, if we did not open a hive root key */
|
||||||
|
if (KeyBody->KeyControlBlock->KeyCell !=
|
||||||
|
KeyBody->KeyControlBlock->KeyHive->BaseBlock->RootCell)
|
||||||
|
{
|
||||||
|
DPRINT("Error: Key is not a hive root key!\n");
|
||||||
|
CmpUnlockRegistry();
|
||||||
|
ObDereferenceObject(KeyBody);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the internal API */
|
||||||
|
*HandleCount = CmCountOpenSubKeys(KeyBody->KeyControlBlock,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Unlock the registry */
|
||||||
|
CmpUnlockRegistry();
|
||||||
|
|
||||||
|
/* Dereference the key object */
|
||||||
|
ObDereferenceObject(KeyBody);
|
||||||
|
|
||||||
|
DPRINT("Done.\n");
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -1501,6 +1501,13 @@ CmUnloadKey(
|
||||||
IN ULONG Flags
|
IN ULONG Flags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
CmCountOpenSubKeys(
|
||||||
|
IN PCM_KEY_CONTROL_BLOCK RootKcb,
|
||||||
|
IN BOOLEAN RemoveEmptyCacheEntries
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Startup and Shutdown
|
// Startup and Shutdown
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue