mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
[NTOSKRNL]
- Update CM_KEY_CONTROL_BLOCK to match win2k3 SP2 symbols - Implement KeyCachedInformation and KeyFlagsInformation cases in CmQueryKey svn path=/trunk/; revision=61572
This commit is contained in:
parent
e5813955cb
commit
8d73b77251
2 changed files with 258 additions and 82 deletions
|
@ -1304,6 +1304,162 @@ Quickie:
|
|||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
CmpQueryKeyDataFromCache(
|
||||
_In_ PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
_Out_ PKEY_CACHED_INFORMATION KeyCachedInfo,
|
||||
_In_ ULONG Length,
|
||||
_Out_ PULONG ResultLength)
|
||||
{
|
||||
PCM_KEY_NODE Node;
|
||||
ULONG SubKeyCount;
|
||||
PHHIVE KeyHive;
|
||||
HCELL_INDEX KeyCell;
|
||||
USHORT NameLength;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the hive and cell index */
|
||||
KeyHive = Kcb->KeyHash.KeyHive;
|
||||
KeyCell = Kcb->KeyHash.KeyCell;
|
||||
|
||||
#if DBG
|
||||
/* Get the cell node */
|
||||
Node = HvGetCell(KeyHive, KeyCell);
|
||||
if (Node != NULL)
|
||||
{
|
||||
ASSERT(Node->ValueList.Count == Kcb->ValueCache.Count);
|
||||
|
||||
if (!(Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO))
|
||||
{
|
||||
SubKeyCount = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
|
||||
if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
|
||||
{
|
||||
ASSERT(SubKeyCount == 0);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
|
||||
{
|
||||
ASSERT(SubKeyCount == 1);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
|
||||
{
|
||||
ASSERT(SubKeyCount == Kcb->IndexHint->Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(SubKeyCount == Kcb->SubKeyCount);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(Node->LastWriteTime.QuadPart == Kcb->KcbLastWriteTime.QuadPart);
|
||||
ASSERT(Node->MaxNameLen == Kcb->KcbMaxNameLen);
|
||||
ASSERT(Node->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
|
||||
ASSERT(Node->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
|
||||
|
||||
/* Release the cell */
|
||||
HvReleaseCell(KeyHive, KeyCell);
|
||||
}
|
||||
#endif // DBG
|
||||
|
||||
/* Make sure we have a name block */
|
||||
if (Kcb->NameBlock == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Check for compressed name */
|
||||
if (Kcb->NameBlock->Compressed)
|
||||
{
|
||||
/* Calculate the name size */
|
||||
NameLength = CmpCompressedNameSize(Kcb->NameBlock->NameHash.Name,
|
||||
Kcb->NameBlock->NameHash.NameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the stored name size */
|
||||
NameLength = Kcb->NameBlock->NameHash.NameLength;
|
||||
}
|
||||
|
||||
/* Validate buffer length (we do not copy the name!) */
|
||||
*ResultLength = sizeof(KeyCachedInfo);
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Fill the structure */
|
||||
KeyCachedInfo->LastWriteTime = Kcb->KcbLastWriteTime;
|
||||
KeyCachedInfo->TitleIndex = 0;
|
||||
KeyCachedInfo->NameLength = NameLength;
|
||||
KeyCachedInfo->Values = Kcb->ValueCache.Count;
|
||||
KeyCachedInfo->MaxNameLen = Kcb->KcbMaxNameLen;
|
||||
KeyCachedInfo->MaxValueNameLen = Kcb->KcbMaxValueNameLen;
|
||||
KeyCachedInfo->MaxValueDataLen = Kcb->KcbMaxValueDataLen;
|
||||
|
||||
/* Check the ExtFlags for what we have */
|
||||
if (Kcb->ExtFlags & CM_KCB_INVALID_CACHED_INFO)
|
||||
{
|
||||
/* Cache is not valid, do a full lookup */
|
||||
DPRINT1("Kcb cache incoherency detected, kcb = %p\n", Kcb);
|
||||
|
||||
/* Get the cell node */
|
||||
Node = HvGetCell(KeyHive, KeyCell);
|
||||
if (Node == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Calculate number of subkeys */
|
||||
KeyCachedInfo->SubKeys = Node->SubKeyCounts[0] + Node->SubKeyCounts[1];
|
||||
|
||||
/* Release the cell */
|
||||
HvReleaseCell(KeyHive, KeyCell);
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_NO_SUBKEY)
|
||||
{
|
||||
/* There are no subkeys */
|
||||
KeyCachedInfo->SubKeys = 0;
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_ONE)
|
||||
{
|
||||
/* There is exactly one subley */
|
||||
KeyCachedInfo->SubKeys = 1;
|
||||
}
|
||||
else if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT)
|
||||
{
|
||||
/* Get the number of subkeys from the subkey hint */
|
||||
KeyCachedInfo->SubKeys = Kcb->IndexHint->Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No subkey hint, use the key count field */
|
||||
KeyCachedInfo->SubKeys = Kcb->SubKeyCount;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
CmpQueryFlagsInformation(
|
||||
_In_ PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
_Out_ PKEY_USER_FLAGS_INFORMATION KeyFlagsInfo,
|
||||
_In_ ULONG Length,
|
||||
_In_ PULONG ResultLength)
|
||||
{
|
||||
/* Validate the buffer size */
|
||||
*ResultLength = sizeof(*KeyFlagsInfo);
|
||||
if (Length < *ResultLength)
|
||||
{
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
/* Copy the user flags */
|
||||
KeyFlagsInfo->UserFlags = Kcb->KcbUserFlags;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
||||
|
@ -1362,10 +1518,24 @@ CmQueryKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
|
|||
}
|
||||
break;
|
||||
|
||||
/* Unsupported classes for now */
|
||||
case KeyNameInformation:
|
||||
case KeyCachedInformation:
|
||||
/* Call the internal API */
|
||||
Status = CmpQueryKeyDataFromCache(Kcb,
|
||||
KeyInformation,
|
||||
Length,
|
||||
ResultLength);
|
||||
break;
|
||||
|
||||
case KeyFlagsInformation:
|
||||
/* Call the internal API */
|
||||
Status = CmpQueryFlagsInformation(Kcb,
|
||||
KeyInformation,
|
||||
Length,
|
||||
ResultLength);
|
||||
break;
|
||||
|
||||
/* Unsupported class for now */
|
||||
case KeyNameInformation:
|
||||
|
||||
/* Print message and fail */
|
||||
DPRINT1("Unsupported class: %d!\n", KeyInformationClass);
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define CM_KCB_INVALID_SIGNATURE '4FmC'
|
||||
|
||||
//
|
||||
// CM_KEY_CONTROL_BLOCK Flags
|
||||
// CM_KEY_CONTROL_BLOCK ExtFlags
|
||||
//
|
||||
#define CM_KCB_NO_SUBKEY 0x01
|
||||
#define CM_KCB_SUBKEY_ONE 0x02
|
||||
|
@ -253,8 +253,7 @@ typedef struct _CM_NAME_CONTROL_BLOCK
|
|||
typedef struct _CM_KEY_CONTROL_BLOCK
|
||||
{
|
||||
ULONG Signature;
|
||||
USHORT RefCount;
|
||||
USHORT Flags;
|
||||
ULONG RefCount;
|
||||
struct
|
||||
{
|
||||
ULONG ExtFlags:8;
|
||||
|
@ -295,6 +294,13 @@ typedef struct _CM_KEY_CONTROL_BLOCK
|
|||
USHORT KcbMaxNameLen;
|
||||
USHORT KcbMaxValueNameLen;
|
||||
ULONG KcbMaxValueDataLen;
|
||||
struct
|
||||
{
|
||||
ULONG KcbUserFlags : 4;
|
||||
ULONG KcbVirtControlFlags : 4;
|
||||
ULONG KcbDebug : 8;
|
||||
ULONG Flags : 16;
|
||||
};
|
||||
ULONG InDelayClose;
|
||||
} CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;
|
||||
|
||||
|
|
Loading…
Reference in a new issue