ReactOS  0.4.14-dev-115-g4576127
cmkcbncb.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for cmkcbncb.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

INIT_FUNCTION VOID NTAPI CmpInitializeCache (VOID)
 
VOID NTAPI CmpRemoveKeyHash (IN PCM_KEY_HASH KeyHash)
 
PCM_KEY_CONTROL_BLOCK NTAPI CmpInsertKeyHash (IN PCM_KEY_HASH KeyHash, IN BOOLEAN IsFake)
 
PCM_NAME_CONTROL_BLOCK NTAPI CmpGetNameControlBlock (IN PUNICODE_STRING NodeName)
 
VOID NTAPI CmpRemoveKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpDereferenceNameControlBlockWithLock (IN PCM_NAME_CONTROL_BLOCK Ncb)
 
BOOLEAN NTAPI CmpReferenceKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpCleanUpKcbValueCache (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpCleanUpKcbCacheWithLock (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
 
VOID NTAPI CmpCleanUpSubKeyInfo (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpDereferenceKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpDereferenceKeyControlBlockWithLock (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
 
VOID NTAPI InitializeKCBKeyBodyList (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock (IN PHHIVE Hive, IN HCELL_INDEX Index, IN PCM_KEY_NODE Node, IN PCM_KEY_CONTROL_BLOCK Parent, IN ULONG Flags, IN PUNICODE_STRING KeyName)
 
PUNICODE_STRING NTAPI CmpConstructName (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI EnlistKeyBodyWithKCB (IN PCM_KEY_BODY KeyBody, IN ULONG Flags)
 
VOID NTAPI DelistKeyBodyFromKCB (IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
 
VOID NTAPI CmpFlushNotifiesOnKeyBodyList (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
 

Variables

ULONG CmpHashTableSize = 2048
 
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
 
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file cmkcbncb.c.

Function Documentation

◆ CmpCleanUpKcbCacheWithLock()

VOID NTAPI CmpCleanUpKcbCacheWithLock ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN BOOLEAN  LockHeldExclusively 
)

Definition at line 476 of file cmkcbncb.c.

478 {
480  PAGED_CODE();
481 
482  /* Sanity checks */
483  CMP_ASSERT_KCB_LOCK(Kcb);
484  ASSERT(Kcb->RefCount == 0);
485 
486  /* Cleanup the value cache */
488 
489  /* Dereference the NCB */
491 
492  /* Check if we have an index hint block and free it */
493  if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT) CmpFree(Kcb->IndexHint, 0);
494 
495  /* Check if we were already deleted */
496  Parent = Kcb->ParentKcb;
497  if (!Kcb->Delete) CmpRemoveKeyControlBlock(Kcb);
498 
499  /* Set invalid KCB signature */
500  Kcb->Signature = CM_KCB_INVALID_SIGNATURE;
501 
502  /* Free the KCB as well */
504 
505  /* Check if we have a parent */
506  if (Parent)
507  {
508  /* Dereference the parent */
509  LockHeldExclusively ?
510  CmpDereferenceKeyControlBlockWithLock(Parent,LockHeldExclusively) :
512  }
513 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:722
VOID NTAPI CmpDelayDerefKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:286
#define PAGED_CODE()
Definition: video.h:57
#define CM_KCB_INVALID_SIGNATURE
Definition: cm.h:49
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define CM_KCB_SUBKEY_HINT
Definition: cm.h:56
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb)
Definition: cmkcbncb.c:317
VOID NTAPI CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmalloc.c:53
VOID NTAPI CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:606
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431

Referenced by _Function_class_(), CmpAddToDelayedClose(), CmpDereferenceKeyControlBlockWithLock(), and CmpEnumerateOpenSubKeys().

◆ CmpCleanUpKcbValueCache()

VOID NTAPI CmpCleanUpKcbValueCache ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 431 of file cmkcbncb.c.

432 {
433  PULONG_PTR CachedList;
434  ULONG i;
435 
436  /* Make sure we have the exclusive lock */
437  CMP_ASSERT_KCB_LOCK(Kcb);
438 
439  /* Check if the value list is cached */
440  if (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))
441  {
442  /* Get the cache list */
443  CachedList = (PULONG_PTR)CMP_GET_CACHED_DATA(Kcb->ValueCache.ValueList);
444  for (i = 0; i < Kcb->ValueCache.Count; i++)
445  {
446  /* Check if this cell is cached */
447  if (CMP_IS_CELL_CACHED(CachedList[i]))
448  {
449  /* Free it */
450  CmpFree((PVOID)CMP_GET_CACHED_CELL(CachedList[i]), 0);
451  }
452  }
453 
454  /* Now free the list */
455  CmpFree((PVOID)CMP_GET_CACHED_CELL(Kcb->ValueCache.ValueList), 0);
456  Kcb->ValueCache.ValueList = HCELL_NIL;
457  }
458  else if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
459  {
460  /* This is a sym link, check if there's only one reference left */
461  if ((Kcb->ValueCache.RealKcb->RefCount == 1) &&
462  !(Kcb->ValueCache.RealKcb->Delete))
463  {
464  /* Disable delay close for the KCB */
465  Kcb->ValueCache.RealKcb->ExtFlags |= CM_KCB_NO_DELAY_CLOSE;
466  }
467 
468  /* Dereference the KCB */
469  CmpDelayDerefKeyControlBlock(Kcb->ValueCache.RealKcb);
470  Kcb->ExtFlags &= ~CM_KCB_SYM_LINK_FOUND;
471  }
472 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
#define HCELL_NIL
Definition: hivedata.h:85
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:28
#define CM_KCB_NO_DELAY_CLOSE
Definition: cm.h:59
VOID NTAPI CmpDelayDerefKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:286
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define CMP_GET_CACHED_DATA(c)
Definition: cm_x.h:36
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define CMP_GET_CACHED_CELL(c)
Definition: cm_x.h:34
unsigned int ULONG
Definition: retypes.h:1
uint32_t * PULONG_PTR
Definition: typedefs.h:63
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57

Referenced by CmDeleteValueKey(), CmpCleanUpKcbCacheWithLock(), CmpCompareNewValueDataAgainstKCBCache(), and CmSetValueKey().

◆ CmpCleanUpSubKeyInfo()

VOID NTAPI CmpCleanUpSubKeyInfo ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 517 of file cmkcbncb.c.

518 {
519  PCM_KEY_NODE KeyNode;
520 
521  /* Make sure we have the exclusive lock */
522  CMP_ASSERT_KCB_LOCK(Kcb);
523 
524  /* Check if there's any cached subkey */
525  if (Kcb->ExtFlags & (CM_KCB_NO_SUBKEY | CM_KCB_SUBKEY_ONE | CM_KCB_SUBKEY_HINT))
526  {
527  /* Check if there's a hint */
528  if (Kcb->ExtFlags & (CM_KCB_SUBKEY_HINT))
529  {
530  /* Kill it */
531  CmpFree(Kcb->IndexHint, 0);
532  }
533 
534  /* Remove subkey flags */
535  Kcb->ExtFlags &= ~(CM_KCB_NO_SUBKEY | CM_KCB_SUBKEY_ONE | CM_KCB_SUBKEY_HINT);
536  }
537 
538  /* Check if there's no linked cell */
539  if (Kcb->KeyCell == HCELL_NIL)
540  {
541  /* Make sure it's a delete */
542  ASSERT(Kcb->Delete);
543  KeyNode = NULL;
544  }
545  else
546  {
547  /* Get the key node */
548  KeyNode = (PCM_KEY_NODE)HvGetCell(Kcb->KeyHive, Kcb->KeyCell);
549  }
550 
551  /* Check if we got the node */
552  if (!KeyNode)
553  {
554  /* We didn't, mark the cached data invalid */
555  Kcb->ExtFlags |= CM_KCB_INVALID_CACHED_INFO;
556  }
557  else
558  {
559  /* We have a keynode, update subkey counts */
560  Kcb->ExtFlags &= ~CM_KCB_INVALID_CACHED_INFO;
561  Kcb->SubKeyCount = KeyNode->SubKeyCounts[Stable] +
562  KeyNode->SubKeyCounts[Volatile];
563 
564  /* Release the cell */
565  HvReleaseCell(Kcb->KeyHive, Kcb->KeyCell);
566  }
567 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
#define CM_KCB_NO_SUBKEY
Definition: cm.h:54
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define HCELL_NIL
Definition: hivedata.h:85
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
#define CM_KCB_SUBKEY_ONE
Definition: cm.h:55
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
#define CM_KCB_INVALID_CACHED_INFO
Definition: cm.h:60
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97
#define CM_KCB_SUBKEY_HINT
Definition: cm.h:56
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by CmDeleteKey(), CmpEnumerateOpenSubKeys(), and CmUnloadKey().

◆ CmpConstructName()

PUNICODE_STRING NTAPI CmpConstructName ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 897 of file cmkcbncb.c.

898 {
900  ULONG i;
901  USHORT NameLength;
902  PCM_KEY_CONTROL_BLOCK MyKcb;
903  PCM_KEY_NODE KeyNode;
904  BOOLEAN DeletedKey = FALSE;
905  PWCHAR TargetBuffer, CurrentNameW;
906  PUCHAR CurrentName;
907 
908  /* Calculate how much size our key name is going to occupy */
909  NameLength = 0;
910  MyKcb = Kcb;
911 
912  while (MyKcb)
913  {
914  /* Add length of the name */
915  if (!MyKcb->NameBlock->Compressed)
916  {
917  NameLength += MyKcb->NameBlock->NameLength;
918  }
919  else
920  {
921  NameLength += CmpCompressedNameSize(MyKcb->NameBlock->Name,
922  MyKcb->NameBlock->NameLength);
923  }
924 
925  /* Sum up the separator too */
926  NameLength += sizeof(WCHAR);
927 
928  /* Go to the parent KCB */
929  MyKcb = MyKcb->ParentKcb;
930  }
931 
932  /* Allocate the unicode string now */
933  KeyName = CmpAllocate(NameLength + sizeof(UNICODE_STRING),
934  TRUE,
935  TAG_CM);
936 
937  if (!KeyName) return NULL;
938 
939  /* Set it up */
940  KeyName->Buffer = (PWSTR)(KeyName + 1);
941  KeyName->Length = NameLength;
942  KeyName->MaximumLength = NameLength;
943 
944  /* Loop the keys again, now adding names */
945  NameLength = 0;
946  MyKcb = Kcb;
947 
948  while (MyKcb)
949  {
950  /* Sanity checks for deleted and fake keys */
951  if ((!MyKcb->KeyCell && !MyKcb->Delete) ||
952  !MyKcb->KeyHive ||
954  {
955  /* Failure */
956  CmpFree(KeyName, 0);
957  return NULL;
958  }
959 
960  /* Try to get the name from the keynode,
961  if the key is not deleted */
962  if (!DeletedKey && !MyKcb->Delete)
963  {
964  KeyNode = HvGetCell(MyKcb->KeyHive, MyKcb->KeyCell);
965 
966  if (!KeyNode)
967  {
968  /* Failure */
969  CmpFree(KeyName, 0);
970  return NULL;
971  }
972  }
973  else
974  {
975  /* The key was deleted */
976  KeyNode = NULL;
977  DeletedKey = TRUE;
978  }
979 
980  /* Get the pointer to the beginning of the current key name */
981  NameLength += (MyKcb->NameBlock->NameLength + 1) * sizeof(WCHAR);
982  TargetBuffer = &KeyName->Buffer[(KeyName->Length - NameLength) / sizeof(WCHAR)];
983 
984  /* Add a separator */
985  TargetBuffer[0] = OBJ_NAME_PATH_SEPARATOR;
986 
987  /* Add the name, but remember to go from the end to the beginning */
988  if (!MyKcb->NameBlock->Compressed)
989  {
990  /* Get the pointer to the name (from the keynode, if possible) */
991  if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
992  !KeyNode)
993  {
994  CurrentNameW = MyKcb->NameBlock->Name;
995  }
996  else
997  {
998  CurrentNameW = KeyNode->Name;
999  }
1000 
1001  /* Copy the name */
1002  for (i=0; i < MyKcb->NameBlock->NameLength; i++)
1003  {
1004  TargetBuffer[i+1] = *CurrentNameW;
1005  CurrentNameW++;
1006  }
1007  }
1008  else
1009  {
1010  /* Get the pointer to the name (from the keynode, if possible) */
1011  if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
1012  !KeyNode)
1013  {
1014  CurrentName = (PUCHAR)MyKcb->NameBlock->Name;
1015  }
1016  else
1017  {
1018  CurrentName = (PUCHAR)KeyNode->Name;
1019  }
1020 
1021  /* Copy the name */
1022  for (i=0; i < MyKcb->NameBlock->NameLength; i++)
1023  {
1024  TargetBuffer[i+1] = (WCHAR)*CurrentName;
1025  CurrentName++;
1026  }
1027  }
1028 
1029  /* Release the cell, if needed */
1030  if (KeyNode) HvReleaseCell(MyKcb->KeyHive, MyKcb->KeyCell);
1031 
1032  /* Go to the parent KCB */
1033  MyKcb = MyKcb->ParentKcb;
1034  }
1035 
1036  /* Return resulting buffer (both UNICODE_STRING and
1037  its buffer following it) */
1038  return KeyName;
1039 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
#define TRUE
Definition: types.h:120
ULONG ExtFlags
Definition: cm.h:264
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:281
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned char * PUCHAR
Definition: retypes.h:3
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
HCELL_INDEX KeyCell
Definition: cm.h:278
PCM_NAME_CONTROL_BLOCK NameBlock
Definition: cm.h:282
uint16_t * PWCHAR
Definition: typedefs.h:54
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
USHORT NameLength
Definition: cm.h:249
BOOLEAN Compressed
Definition: cm.h:240
#define KEY_HIVE_EXIT
Definition: cmdata.h:31
__wchar_t WCHAR
Definition: xmlstorage.h:180
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define TAG_CM
Definition: cmlib.h:203
PHHIVE KeyHive
Definition: cm.h:277
#define CM_KCB_KEY_NON_EXIST
Definition: cm.h:58
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:250
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32

Referenced by CmpQueryKeyName().

◆ CmpCreateKeyControlBlock()

PCM_KEY_CONTROL_BLOCK NTAPI CmpCreateKeyControlBlock ( IN PHHIVE  Hive,
IN HCELL_INDEX  Index,
IN PCM_KEY_NODE  Node,
IN PCM_KEY_CONTROL_BLOCK  Parent,
IN ULONG  Flags,
IN PUNICODE_STRING  KeyName 
)

Definition at line 655 of file cmkcbncb.c.

661 {
662  PCM_KEY_CONTROL_BLOCK Kcb, FoundKcb = NULL;
664  ULONG ConvKey = 0, i;
665  BOOLEAN IsFake, HashLock;
666  PWCHAR p;
667 
668  /* Make sure we own this hive in case it's being unloaded */
669  if ((Hive->HiveFlags & HIVE_IS_UNLOADING) &&
670  (((PCMHIVE)Hive)->CreatorOwner != KeGetCurrentThread()))
671  {
672  /* Fail */
673  return NULL;
674  }
675 
676  /* Check if this is a fake KCB */
677  IsFake = Flags & CMP_CREATE_FAKE_KCB ? TRUE : FALSE;
678 
679  /* If we have a parent, use its ConvKey */
680  if (Parent) ConvKey = Parent->ConvKey;
681 
682  /* Make a copy of the name */
683  NodeName = *KeyName;
684 
685  /* Remove leading slash */
686  while ((NodeName.Length) && (*NodeName.Buffer == OBJ_NAME_PATH_SEPARATOR))
687  {
688  /* Move the buffer by one */
689  NodeName.Buffer++;
690  NodeName.Length -= sizeof(WCHAR);
691  }
692 
693  /* Make sure we didn't get just a slash or something */
694  ASSERT(NodeName.Length > 0);
695 
696  /* Now setup the hash */
697  p = NodeName.Buffer;
698  for (i = 0; i < NodeName.Length; i += sizeof(WCHAR))
699  {
700  /* Make sure it's a valid character */
701  if (*p != OBJ_NAME_PATH_SEPARATOR)
702  {
703  /* Add this key to the hash */
704  ConvKey = 37 * ConvKey + RtlUpcaseUnicodeChar(*p);
705  }
706 
707  /* Move on */
708  p++;
709  }
710 
711  /* Allocate the KCB */
713  if (!Kcb) return NULL;
714 
715  /* Initailize the key list */
717 
718  /* Set it up */
720  Kcb->Delete = FALSE;
721  Kcb->RefCount = 1;
722  Kcb->KeyHive = Hive;
723  Kcb->KeyCell = Index;
724  Kcb->ConvKey = ConvKey;
726  Kcb->InDelayClose = 0;
727  ASSERT_KCB_VALID(Kcb);
728 
729  /* Check if we have two hash entires */
730  HashLock = Flags & CMP_LOCK_HASHES_FOR_KCB ? TRUE : FALSE;
731  if (!HashLock)
732  {
733  /* It's not locked, do we have a parent? */
734  if (Parent)
735  {
736  /* Lock the parent KCB and ourselves */
737  CmpAcquireTwoKcbLocksExclusiveByKey(ConvKey, Parent->ConvKey);
738  }
739  else
740  {
741  /* Lock only ourselves */
743  }
744  }
745 
746  /* Check if we already have a KCB */
747  FoundKcb = CmpInsertKeyHash(&Kcb->KeyHash, IsFake);
748  if (FoundKcb)
749  {
750  /* Sanity check */
751  ASSERT(!FoundKcb->Delete);
753 
754  /* Free the one we allocated and reference this one */
756  ASSERT_KCB_VALID(FoundKcb);
757  Kcb = FoundKcb;
758  if (!CmpReferenceKeyControlBlock(Kcb))
759  {
760  /* We got too many handles */
761  ASSERT(Kcb->RefCount + 1 != 0);
762  Kcb = NULL;
763  }
764  else
765  {
766  /* Check if we're not creating a fake one, but it used to be fake */
767  if ((Kcb->ExtFlags & CM_KCB_KEY_NON_EXIST) && !(IsFake))
768  {
769  /* Set the hive and cell */
770  Kcb->KeyHive = Hive;
771  Kcb->KeyCell = Index;
772 
773  /* This means that our current information is invalid */
775  }
776 
777  /* Check if we didn't have any valid data */
778  if (!(Kcb->ExtFlags & (CM_KCB_NO_SUBKEY |
781  {
782  /* Calculate the index hint */
783  Kcb->SubKeyCount = Node->SubKeyCounts[Stable] +
784  Node->SubKeyCounts[Volatile];
785 
786  /* Cached information is now valid */
788  }
789 
790  /* Setup the other data */
791  Kcb->KcbLastWriteTime = Node->LastWriteTime;
792  Kcb->KcbMaxNameLen = (USHORT)Node->MaxNameLen;
793  Kcb->KcbMaxValueNameLen = (USHORT)Node->MaxValueNameLen;
794  Kcb->KcbMaxValueDataLen = Node->MaxValueDataLen;
795  }
796  }
797  else
798  {
799  /* No KCB, do we have a parent? */
800  if (Parent)
801  {
802  /* Reference the parent */
803  if (((Parent->TotalLevels + 1) < 512) &&
805  {
806  /* Link it */
807  Kcb->ParentKcb = Parent;
808  Kcb->TotalLevels = Parent->TotalLevels + 1;
809  }
810  else
811  {
812  /* Remove the KCB and free it */
816  Kcb = NULL;
817  }
818  }
819  else
820  {
821  /* No parent, this is the root node */
822  Kcb->ParentKcb = NULL;
823  Kcb->TotalLevels = 1;
824  }
825 
826  /* Check if we have a KCB */
827  if (Kcb)
828  {
829  /* Get the NCB */
831  if (Kcb->NameBlock)
832  {
833  /* Fill it out */
834  Kcb->ValueCache.Count = Node->ValueList.Count;
835  Kcb->ValueCache.ValueList = Node->ValueList.List;
836  Kcb->Flags = Node->Flags;
837  Kcb->ExtFlags = 0;
839 
840  /* Remember if this is a fake key */
841  if (IsFake) Kcb->ExtFlags |= CM_KCB_KEY_NON_EXIST;
842 
843  /* Setup the other data */
844  Kcb->SubKeyCount = Node->SubKeyCounts[Stable] +
845  Node->SubKeyCounts[Volatile];
846  Kcb->KcbLastWriteTime = Node->LastWriteTime;
847  Kcb->KcbMaxNameLen = (USHORT)Node->MaxNameLen;
848  Kcb->KcbMaxValueNameLen = (USHORT)Node->MaxValueNameLen;
849  Kcb->KcbMaxValueDataLen = (USHORT)Node->MaxValueDataLen;
850  }
851  else
852  {
853  /* Dereference the KCB */
855 
856  /* Remove the KCB and free it */
860  Kcb = NULL;
861  }
862  }
863  }
864 
865  /* Check if this is a KCB inside a frozen hive */
866  if ((Kcb) && (((PCMHIVE)Hive)->Frozen) && (!(Kcb->Flags & KEY_SYM_LINK)))
867  {
868  /* Don't add these to the delay close */
870  }
871 
872  /* Sanity check */
873  ASSERT((!Kcb) || (Kcb->Delete == FALSE));
874 
875  /* Check if we had locked the hashes */
876  if (!HashLock)
877  {
878  /* We locked them manually, do we have a parent? */
879  if (Parent)
880  {
881  /* Unlock the parent KCB and ourselves */
882  CmpReleaseTwoKcbLockByKey(ConvKey, Parent->ConvKey);
883  }
884  else
885  {
886  /* Unlock only ourselves */
887  CmpReleaseKcbLockByKey(ConvKey);
888  }
889  }
890 
891  /* Return the KCB */
892  return Kcb;
893 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
BOOLEAN NTAPI CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:357
ULONG CmpDelayedCloseSize
Definition: cmdelay.c:19
#define TRUE
Definition: types.h:120
ULONG Signature
Definition: cm.h:260
ULONG ExtFlags
Definition: cm.h:264
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:281
#define CM_KCB_NO_SUBKEY
Definition: cm.h:54
CACHED_CHILD_LIST ValueCache
Definition: cm.h:284
ULONG ValueList
Definition: cm.h:209
HCELL_INDEX KeyCell
Definition: cm.h:278
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:722
PCM_NAME_CONTROL_BLOCK NameBlock
Definition: cm.h:282
uint16_t * PWCHAR
Definition: typedefs.h:54
#define CM_KCB_NO_DELAY_CLOSE
Definition: cm.h:59
ULONG TotalLevels
Definition: cm.h:268
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
LARGE_INTEGER KcbLastWriteTime
Definition: cm.h:298
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2050
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
USHORT KcbMaxValueNameLen
Definition: cm.h:300
ULONG Count
Definition: cm.h:206
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
ULONG InDelayClose
Definition: cm.h:309
PCM_KEY_CONTROL_BLOCK NTAPI CmpInsertKeyHash(IN PCM_KEY_HASH KeyHash, IN BOOLEAN IsFake)
Definition: cmkcbncb.c:109
#define CM_KCB_SUBKEY_ONE
Definition: cm.h:55
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define HIVE_IS_UNLOADING
Definition: hivedata.h:28
#define CM_KCB_INVALID_SIGNATURE
Definition: cm.h:49
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:179
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
#define CM_KCB_INVALID_CACHED_INFO
Definition: cm.h:60
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CMP_CREATE_FAKE_KCB
Definition: cm.h:90
static const UCHAR Index[8]
Definition: usbohci.c:18
#define CM_KCB_SUBKEY_HINT
Definition: cm.h:56
ULONG DelayedCloseIndex
Definition: cm.h:267
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PCM_KEY_CONTROL_BLOCK NTAPI CmpAllocateKeyControlBlock(VOID)
Definition: cmalloc.c:111
static const char * NodeName(const NOTIFICATIONLIST *item)
Definition: changenotify.c:145
PHHIVE KeyHive
Definition: cm.h:277
#define CMP_LOCK_HASHES_FOR_KCB
Definition: cm.h:91
#define CM_KCB_KEY_NON_EXIST
Definition: cm.h:58
#define KEY_SYM_LINK
Definition: cmdata.h:34
unsigned short USHORT
Definition: pedump.c:61
VOID NTAPI CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmalloc.c:53
ULONG SubKeyCount
Definition: cm.h:289
VOID NTAPI InitializeKCBKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:641
VOID NTAPI CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:606
USHORT KcbMaxNameLen
Definition: cm.h:299
unsigned int ULONG
Definition: retypes.h:1
ULONG RefCount
Definition: cm.h:261
CM_KEY_HASH KeyHash
Definition: cm.h:272
GLfloat GLfloat p
Definition: glext.h:8902
#define KeGetCurrentThread
Definition: hal.h:44
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102
#define CM_KCB_SIGNATURE
Definition: cm.h:48
ULONG KcbMaxValueDataLen
Definition: cm.h:301
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2021
Definition: cm.h:391
#define ASSERT_KCB_VALID(k)
Definition: cm_x.h:76
Definition: dlist.c:348
PCM_NAME_CONTROL_BLOCK NTAPI CmpGetNameControlBlock(IN PUNICODE_STRING NodeName)
Definition: cmkcbncb.c:148

Referenced by CmpCreateRegistryRoot(), CmpDoCreateChild(), CmpDoOpen(), and CmpParseKey().

◆ CmpDereferenceKeyControlBlock()

VOID NTAPI CmpDereferenceKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 571 of file cmkcbncb.c.

572 {
573  LONG OldRefCount, NewRefCount;
574  ULONG ConvKey;
576  "%s - Dereferencing KCB: %p\n", __FUNCTION__, Kcb);
577 
578  /* Get the ref count and update it */
579  OldRefCount = *(PLONG)&Kcb->RefCount;
580  NewRefCount = OldRefCount - 1;
581 
582  /* Check if we still have references */
583  if ((NewRefCount & 0xFFFF) > 0)
584  {
585  /* Do the dereference */
586  if (InterlockedCompareExchange((PLONG)&Kcb->RefCount,
587  NewRefCount,
588  OldRefCount) == OldRefCount)
589  {
590  /* We'de done */
591  return;
592  }
593  }
594 
595  /* Save the key */
596  ConvKey = Kcb->ConvKey;
597 
598  /* Do the dereference inside the lock */
601  CmpReleaseKcbLockByKey(ConvKey);
602 }
#define CMTRACE(x, fmt,...)
Definition: cm.h:36
#define CM_REFERENCE_DEBUG
Definition: cm.h:22
#define InterlockedCompareExchange
Definition: interlocked.h:104
long LONG
Definition: pedump.c:60
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:179
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:606
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102
#define __FUNCTION__
Definition: types.h:112
signed int * PLONG
Definition: retypes.h:5

Referenced by CmpParseKey().

◆ CmpDereferenceKeyControlBlockWithLock()

VOID NTAPI CmpDereferenceKeyControlBlockWithLock ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN BOOLEAN  LockHeldExclusively 
)

Definition at line 606 of file cmkcbncb.c.

608 {
610  "%s - Dereferencing KCB: %p\n", __FUNCTION__, Kcb);
611 
612  /* Sanity check */
613  ASSERT_KCB_VALID(Kcb);
614 
615  /* Check if this is the last reference */
616  if ((InterlockedDecrement((PLONG)&Kcb->RefCount) & 0xFFFF) == 0)
617  {
618  /* Make sure we have the exclusive lock */
619  CMP_ASSERT_KCB_LOCK(Kcb);
620 
621  /* Check if we should do a direct delete */
622  if (((CmpHoldLazyFlush) &&
623  !(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) &&
624  !(Kcb->Flags & KEY_SYM_LINK)) ||
625  (Kcb->ExtFlags & CM_KCB_NO_DELAY_CLOSE) ||
626  (Kcb->Delete))
627  {
628  /* Clean up the KCB*/
629  CmpCleanUpKcbCacheWithLock(Kcb, LockHeldExclusively);
630  }
631  else
632  {
633  /* Otherwise, use delayed close */
634  CmpAddToDelayedClose(Kcb, LockHeldExclusively);
635  }
636  }
637 }
#define CMTRACE(x, fmt,...)
Definition: cm.h:36
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
#define CM_REFERENCE_DEBUG
Definition: cm.h:22
#define CM_KCB_NO_DELAY_CLOSE
Definition: cm.h:59
BOOLEAN CmpHoldLazyFlush
Definition: cmlazy.c:24
VOID NTAPI CmpCleanUpKcbCacheWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:476
VOID NTAPI CmpAddToDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmdelay.c:350
#define InterlockedDecrement
Definition: armddk.h:52
#define KEY_SYM_LINK
Definition: cmdata.h:34
#define __FUNCTION__
Definition: types.h:112
signed int * PLONG
Definition: retypes.h:5
#define ASSERT_KCB_VALID(k)
Definition: cm_x.h:76
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57

Referenced by CmpCleanUpKcbCacheWithLock(), CmpCreateKeyControlBlock(), CmpDereferenceKeyControlBlock(), and CmpDoOpen().

◆ CmpDereferenceNameControlBlockWithLock()

VOID NTAPI CmpDereferenceNameControlBlockWithLock ( IN PCM_NAME_CONTROL_BLOCK  Ncb)

Definition at line 317 of file cmkcbncb.c.

318 {
319  PCM_NAME_HASH Current, *Next;
320  ULONG ConvKey = Ncb->ConvKey;
321 
322  /* Lock the NCB */
324 
325  /* Decrease the reference count */
326  ASSERT(Ncb->RefCount >= 1);
327  if (!(--Ncb->RefCount))
328  {
329  /* Find the NCB in the table */
330  Next = &GET_HASH_ENTRY(CmpNameCacheTable, Ncb->ConvKey)->Entry;
331  while (TRUE)
332  {
333  /* Check the current entry */
334  Current = *Next;
335  ASSERT(Current != NULL);
336  if (Current == &Ncb->NameHash)
337  {
338  /* Unlink it */
339  *Next = Current->NextHash;
340  break;
341  }
342 
343  /* Get to the next one */
344  Next = &Current->NextHash;
345  }
346 
347  /* Found it, now free it */
348  CmpFree(Ncb, 0);
349  }
350 
351  /* Release the lock */
352  CmpReleaseNcbLockByKey(ConvKey);
353 }
ULONG ConvKey
Definition: cm.h:165
#define TRUE
Definition: types.h:120
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
Definition: cmkcbncb.c:19
smooth NULL
Definition: ftsmooth.c:416
#define CmpAcquireNcbLockExclusiveByKey(k)
Definition: cm_x.h:208
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:20
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define CmpReleaseNcbLockByKey(k)
Definition: cm_x.h:226
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned int ULONG
Definition: retypes.h:1
struct _CM_NAME_HASH * NextHash
Definition: cm.h:166

Referenced by CmpCleanUpKcbCacheWithLock().

◆ CmpFlushNotifiesOnKeyBodyList()

VOID NTAPI CmpFlushNotifiesOnKeyBodyList ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN BOOLEAN  LockHeld 
)

Definition at line 1140 of file cmkcbncb.c.

1142 {
1143  PLIST_ENTRY NextEntry, ListHead;
1144  PCM_KEY_BODY KeyBody;
1145 
1146  /* Sanity check */
1148  while (TRUE)
1149  {
1150  /* Is the list empty? */
1151  ListHead = &Kcb->KeyBodyListHead;
1152  if (!IsListEmpty(ListHead))
1153  {
1154  /* Loop the list */
1155  NextEntry = ListHead->Flink;
1156  while (NextEntry != ListHead)
1157  {
1158  /* Get the key body */
1159  KeyBody = CONTAINING_RECORD(NextEntry, CM_KEY_BODY, KeyBodyList);
1160  ASSERT(KeyBody->Type == CM_KEY_BODY_TYPE);
1161 
1162  /* Check for notifications */
1163  if (KeyBody->NotifyBlock)
1164  {
1165  /* Is the lock held? */
1166  if (LockHeld)
1167  {
1168  /* Flush it */
1169  CmpFlushNotify(KeyBody, LockHeld);
1170  ASSERT(KeyBody->NotifyBlock == NULL);
1171  continue;
1172  }
1173 
1174  /* Lock isn't held, so we need to take a reference */
1175  if (ObReferenceObjectSafe(KeyBody))
1176  {
1177  /* Now we can flush */
1178  CmpFlushNotify(KeyBody, LockHeld);
1179  ASSERT(KeyBody->NotifyBlock == NULL);
1180 
1181  /* Release the reference we took */
1183  continue;
1184  }
1185  }
1186 
1187  /* Try the next entry */
1188  NextEntry = NextEntry->Flink;
1189  }
1190  }
1191 
1192  /* List has been parsed, exit */
1193  break;
1194  }
1195 }
#define TRUE
Definition: types.h:120
#define CM_KEY_BODY_TYPE
Definition: cm.h:66
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:230
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:24
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:360
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:61
VOID NTAPI CmpFlushNotify(IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
Definition: cmnotify.c:30
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Definition: typedefs.h:117
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:82
ULONG Type
Definition: cm.h:228

Referenced by CmDeleteKey(), CmpEnumerateOpenSubKeys(), and CmUnloadKey().

◆ CmpGetNameControlBlock()

PCM_NAME_CONTROL_BLOCK NTAPI CmpGetNameControlBlock ( IN PUNICODE_STRING  NodeName)

Definition at line 148 of file cmkcbncb.c.

149 {
151  ULONG ConvKey = 0;
152  PWCHAR p, pp;
153  ULONG i;
154  BOOLEAN IsCompressed = TRUE, Found = FALSE;
156  ULONG NcbSize;
157  USHORT Length;
158 
159  /* Loop the name */
160  p = NodeName->Buffer;
161  for (i = 0; i < NodeName->Length; i += sizeof(WCHAR))
162  {
163  /* Make sure it's not a slash */
164  if (*p != OBJ_NAME_PATH_SEPARATOR)
165  {
166  /* Add it to the hash */
167  ConvKey = 37 * ConvKey + RtlUpcaseUnicodeChar(*p);
168  }
169 
170  /* Next character */
171  p++;
172  }
173 
174  /* Set assumed lengh and loop to check */
175  Length = NodeName->Length / sizeof(WCHAR);
176  for (i = 0; i < (NodeName->Length / sizeof(WCHAR)); i++)
177  {
178  /* Check if this is a 16-bit character */
179  if (NodeName->Buffer[i] > (UCHAR)-1)
180  {
181  /* This is the actual size, and we know we're not compressed */
182  Length = NodeName->Length;
183  IsCompressed = FALSE;
184  break;
185  }
186  }
187 
188  /* Lock the NCB entry */
190 
191  /* Get the hash entry */
192  HashEntry = GET_HASH_ENTRY(CmpNameCacheTable, ConvKey)->Entry;
193  while (HashEntry)
194  {
195  /* Get the current NCB */
197 
198  /* Check if the hash matches */
199  if ((ConvKey == HashEntry->ConvKey) && (Length == Ncb->NameLength))
200  {
201  /* Assume success */
202  Found = TRUE;
203 
204  /* If the NCB is compressed, do a compressed name compare */
205  if (Ncb->Compressed)
206  {
207  /* Compare names */
209  {
210  /* We failed */
211  Found = FALSE;
212  }
213  }
214  else
215  {
216  /* Do a manual compare */
217  p = NodeName->Buffer;
218  pp = Ncb->Name;
219  for (i = 0; i < Ncb->NameLength; i += sizeof(WCHAR))
220  {
221  /* Compare the character */
223  {
224  /* Failed */
225  Found = FALSE;
226  break;
227  }
228 
229  /* Next chars */
230  p++;
231  pp++;
232  }
233  }
234 
235  /* Check if we found a name */
236  if (Found)
237  {
238  /* Reference it */
239  ASSERT(Ncb->RefCount != 0xFFFF);
240  Ncb->RefCount++;
241  break;
242  }
243  }
244 
245  /* Go to the next hash */
246  HashEntry = HashEntry->NextHash;
247  }
248 
249  /* Check if we didn't find it */
250  if (!Found)
251  {
252  /* Allocate one */
254  Ncb = CmpAllocate(NcbSize, TRUE, TAG_CM);
255  if (!Ncb)
256  {
257  /* Release the lock and fail */
258  CmpReleaseNcbLockByKey(ConvKey);
259  return NULL;
260  }
261 
262  /* Clear it out */
263  RtlZeroMemory(Ncb, NcbSize);
264 
265  /* Check if the name was compressed */
266  if (IsCompressed)
267  {
268  /* Copy the compressed name */
269  for (i = 0; i < NodeName->Length / sizeof(WCHAR); i++)
270  {
271  /* Copy Unicode to ANSI */
272  ((PCHAR)Ncb->Name)[i] = (CHAR)RtlUpcaseUnicodeChar(NodeName->Buffer[i]);
273  }
274  }
275  else
276  {
277  /* Copy the name directly */
278  for (i = 0; i < NodeName->Length / sizeof(WCHAR); i++)
279  {
280  /* Copy each unicode character */
281  Ncb->Name[i] = RtlUpcaseUnicodeChar(NodeName->Buffer[i]);
282  }
283  }
284 
285  /* Setup the rest of the NCB */
286  Ncb->Compressed = IsCompressed;
287  Ncb->ConvKey = ConvKey;
288  Ncb->RefCount++;
289  Ncb->NameLength = Length;
290 
291  /* Insert the name in the hash table */
292  HashEntry = &Ncb->NameHash;
293  HashEntry->NextHash = GET_HASH_ENTRY(CmpNameCacheTable, ConvKey)->Entry;
294  GET_HASH_ENTRY(CmpNameCacheTable, ConvKey)->Entry = HashEntry;
295  }
296 
297  /* Release NCB lock */
298  CmpReleaseNcbLockByKey(ConvKey);
299 
300  /* Return the NCB found */
301  return Ncb;
302 }
#define TRUE
Definition: types.h:120
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
Definition: cmkcbncb.c:19
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define pp
Definition: hlsl.yy.c:978
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
USHORT NameLength
Definition: cm.h:249
return Found
Definition: dirsup.c:1270
#define CmpAcquireNcbLockExclusiveByKey(k)
Definition: cm_x.h:208
BOOLEAN Compressed
Definition: cm.h:240
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:20
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define CmpReleaseNcbLockByKey(k)
Definition: cm_x.h:226
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TAG_CM
Definition: cmlib.h:203
static const char * NodeName(const NOTIFICATIONLIST *item)
Definition: changenotify.c:145
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:250
Definition: hash.c:61
USHORT RefCount
Definition: cm.h:241
unsigned short USHORT
Definition: pedump.c:61
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
GLfloat GLfloat p
Definition: glext.h:8902
CM_NAME_HASH NameHash
Definition: cm.h:244
#define CHAR(Char)

Referenced by CmpCreateKeyControlBlock().

◆ CmpInitializeCache()

INIT_FUNCTION VOID NTAPI CmpInitializeCache ( VOID  )

Definition at line 26 of file cmkcbncb.c.

27 {
28  ULONG Length, i;
29 
30  /* Calculate length for the table */
32 
33  /* Allocate it */
35  if (!CmpCacheTable)
36  {
37  /* Take the system down */
38  KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 1, 0, 0);
39  }
40 
41  /* Zero out the table */
43 
44  /* Initialize the locks */
45  for (i = 0;i < CmpHashTableSize; i++)
46  {
47  /* Setup the pushlock */
49  }
50 
51  /* Calculate length for the name cache */
53 
54  /* Now allocate the name cache table */
56  if (!CmpNameCacheTable)
57  {
58  /* Take the system down */
59  KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 3, 0, 0);
60  }
61 
62  /* Zero out the table */
64 
65  /* Initialize the locks */
66  for (i = 0;i < CmpHashTableSize; i++)
67  {
68  /* Setup the pushlock */
70  }
71 
72  /* Setup the delayed close table */
74 }
#define TRUE
Definition: types.h:120
struct _CM_KEY_HASH_TABLE_ENTRY CM_KEY_HASH_TABLE_ENTRY
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
Definition: cmkcbncb.c:19
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ExInitializePushLock
Definition: ex.h:999
ULONG CmpHashTableSize
Definition: cmkcbncb.c:17
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
#define TAG_CM
Definition: cmlib.h:203
struct _CM_NAME_HASH_TABLE_ENTRY CM_NAME_HASH_TABLE_ENTRY
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
INIT_FUNCTION VOID NTAPI CmpInitializeDelayedCloseTable(VOID)
Definition: cmdelay.c:191
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107

Referenced by CmInitSystem1().

◆ CmpInsertKeyHash()

PCM_KEY_CONTROL_BLOCK NTAPI CmpInsertKeyHash ( IN PCM_KEY_HASH  KeyHash,
IN BOOLEAN  IsFake 
)

Definition at line 109 of file cmkcbncb.c.

111 {
112  ULONG i;
115 
116  /* Get the hash index */
117  i = GET_HASH_INDEX(KeyHash->ConvKey);
118 
119  /* If this is a fake key, increase the key cell to use the parent data */
120  if (IsFake) KeyHash->KeyCell++;
121 
122  /* Loop the hash table */
124  while (Entry)
125  {
126  /* Check if this matches */
128  if ((KeyHash->ConvKey == Entry->ConvKey) &&
129  (KeyHash->KeyCell == Entry->KeyCell) &&
130  (KeyHash->KeyHive == Entry->KeyHive))
131  {
132  /* Return it */
134  }
135 
136  /* Keep looping */
137  Entry = Entry->NextHash;
138  }
139 
140  /* No entry found, add this one and return NULL since none existed */
141  KeyHash->NextHash = CmpCacheTable[i].Entry;
143  return NULL;
144 }
struct _Entry Entry
Definition: kefuncs.h:640
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT_VALID_HASH(h)
Definition: cm_x.h:22
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
#define GET_HASH_INDEX(ConvKey)
Definition: cm_x.h:18
PCM_KEY_HASH Entry
Definition: cm.h:157
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82

Referenced by CmpCreateKeyControlBlock().

◆ CmpReferenceKeyControlBlock()

BOOLEAN NTAPI CmpReferenceKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 357 of file cmkcbncb.c.

358 {
360  "%s - Referencing KCB: %p\n", __FUNCTION__, Kcb);
361 
362  /* Check if this is the KCB's first reference */
363  if (Kcb->RefCount == 0)
364  {
365  /* Check if the KCB is locked in shared mode */
366  if (!CmpIsKcbLockedExclusive(Kcb))
367  {
368  /* Convert it to exclusive */
370  {
371  /* Set the delayed close index so that we can be ignored */
372  Kcb->DelayedCloseIndex = 1;
373 
374  /* Increase the reference count while we release the lock */
375  InterlockedIncrement((PLONG)&Kcb->RefCount);
376 
377  /* Go from shared to exclusive */
379 
380  /* Decrement the reference count; the lock is now held again */
381  InterlockedDecrement((PLONG)&Kcb->RefCount);
382 
383  /* Check if we still control the index */
384  if (Kcb->DelayedCloseIndex == 1)
385  {
386  /* Reset it */
387  Kcb->DelayedCloseIndex = 0;
388  }
389  else
390  {
391  /* Sanity check */
392  ASSERT((Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ||
393  (Kcb->DelayedCloseIndex == 0));
394  }
395  }
396  }
397  }
398 
399  /* Increase the reference count */
400  if ((InterlockedIncrement((PLONG)&Kcb->RefCount) & 0xFFFF) == 0)
401  {
402  /* We've overflown to 64K references, bail out */
403  InterlockedDecrement((PLONG)&Kcb->RefCount);
404  return FALSE;
405  }
406 
407  /* Check if this was the last close index */
408  if (!Kcb->DelayedCloseIndex)
409  {
410  /* Check if the KCB is locked in shared mode */
411  if (!CmpIsKcbLockedExclusive(Kcb))
412  {
413  /* Convert it to exclusive */
415  {
416  /* Go from shared to exclusive */
418  }
419  }
420 
421  /* If we're still the last entry, remove us */
422  if (!Kcb->DelayedCloseIndex) CmpRemoveFromDelayedClose(Kcb);
423  }
424 
425  /* Return success */
426  return TRUE;
427 }
#define CMTRACE(x, fmt,...)
Definition: cm.h:36
ULONG CmpDelayedCloseSize
Definition: cmdelay.c:19
#define TRUE
Definition: types.h:120
#define CM_REFERENCE_DEBUG
Definition: cm.h:22
VOID NTAPI CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:425
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InterlockedDecrement
Definition: armddk.h:52
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:140
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:189
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:82
#define __FUNCTION__
Definition: types.h:112
signed int * PLONG
Definition: retypes.h:5

Referenced by CmpBuildHashStackAndLookupCache(), CmpCreateKeyControlBlock(), and CmpDoOpen().

◆ CmpRemoveKeyControlBlock()

VOID NTAPI CmpRemoveKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 306 of file cmkcbncb.c.

307 {
308  /* Make sure we have the exclusive lock */
309  CMP_ASSERT_KCB_LOCK(Kcb);
310 
311  /* Remove the key hash */
312  CmpRemoveKeyHash(&Kcb->KeyHash);
313 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
VOID NTAPI CmpRemoveKeyHash(IN PCM_KEY_HASH KeyHash)
Definition: cmkcbncb.c:78

Referenced by CmDeleteKey(), CmpCleanUpKcbCacheWithLock(), CmpCreateKeyControlBlock(), CmpEnumerateOpenSubKeys(), and CmUnloadKey().

◆ CmpRemoveKeyHash()

VOID NTAPI CmpRemoveKeyHash ( IN PCM_KEY_HASH  KeyHash)

Definition at line 78 of file cmkcbncb.c.

79 {
80  PCM_KEY_HASH *Prev;
81  PCM_KEY_HASH Current;
83 
84  /* Lookup all the keys in this index entry */
85  Prev = &GET_HASH_ENTRY(CmpCacheTable, KeyHash->ConvKey)->Entry;
86  while (TRUE)
87  {
88  /* Save the current one and make sure it's valid */
89  Current = *Prev;
90  ASSERT(Current != NULL);
91  ASSERT_VALID_HASH(Current);
92 
93  /* Check if it matches */
94  if (Current == KeyHash)
95  {
96  /* Then write the previous one */
97  *Prev = Current->NextHash;
98  if (*Prev) ASSERT_VALID_HASH(*Prev);
99  break;
100  }
101 
102  /* Otherwise, keep going */
103  Prev = &Current->NextHash;
104  }
105 }
#define TRUE
Definition: types.h:120
#define ASSERT_VALID_HASH(h)
Definition: cm_x.h:22
smooth NULL
Definition: ftsmooth.c:416
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:20
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _CM_KEY_HASH * NextHash
Definition: cm.h:145

Referenced by CmpRemoveKeyControlBlock().

◆ DelistKeyBodyFromKCB()

VOID NTAPI DelistKeyBodyFromKCB ( IN PCM_KEY_BODY  KeyBody,
IN BOOLEAN  LockHeld 
)

Definition at line 1101 of file cmkcbncb.c.

1103 {
1104  ULONG i;
1105 
1106  /* Sanity check */
1107  ASSERT(KeyBody->KeyControlBlock != NULL);
1108 
1109  /* Check if we can use the parent KCB array */
1110  for (i = 0; i < 4; i++)
1111  {
1112  /* Add it into the list */
1113  if (InterlockedCompareExchangePointer((VOID*)&KeyBody->KeyControlBlock->
1114  KeyBodyArray[i],
1115  NULL,
1116  KeyBody) == KeyBody)
1117  {
1118  /* Removed */
1119  return;
1120  }
1121  }
1122 
1123  /* Sanity checks */
1124  ASSERT(IsListEmpty(&KeyBody->KeyControlBlock->KeyBodyListHead) == FALSE);
1125  ASSERT(IsListEmpty(&KeyBody->KeyBodyList) == FALSE);
1126 
1127  /* Lock the KCB */
1128  if (!LockHeld) CmpAcquireKcbLockExclusive(KeyBody->KeyControlBlock);
1129  CMP_ASSERT_KCB_LOCK(KeyBody->KeyControlBlock);
1130 
1131  /* Remove the entry */
1132  RemoveEntryList(&KeyBody->KeyBodyList);
1133 
1134  /* Unlock it it if we did a manual lock */
1135  if (!LockHeld) CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1136 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102

Referenced by CmpDeleteKeyObject().

◆ EnlistKeyBodyWithKCB()

VOID NTAPI EnlistKeyBodyWithKCB ( IN PCM_KEY_BODY  KeyBody,
IN ULONG  Flags 
)

Definition at line 1043 of file cmkcbncb.c.

1045 {
1046  ULONG i;
1047 
1048  /* Sanity check */
1049  ASSERT(KeyBody->KeyControlBlock != NULL);
1050 
1051  /* Initialize the list entry */
1052  InitializeListHead(&KeyBody->KeyBodyList);
1053 
1054  /* Check if we can use the parent KCB array */
1055  for (i = 0; i < 4; i++)
1056  {
1057  /* Add it into the list */
1058  if (!InterlockedCompareExchangePointer((PVOID*)&KeyBody->KeyControlBlock->
1059  KeyBodyArray[i],
1060  KeyBody,
1061  NULL))
1062  {
1063  /* Added */
1064  return;
1065  }
1066  }
1067 
1068  /* Array full, check if we need to unlock the KCB */
1070  {
1071  /* It's shared, so release the KCB shared lock */
1072  CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1074  }
1075 
1076  /* Check if we need to lock the KCB */
1078  {
1079  /* Acquire the lock */
1080  CmpAcquireKcbLockExclusive(KeyBody->KeyControlBlock);
1081  }
1082 
1083  /* Make sure we have the exclusive lock */
1084  CMP_ASSERT_KCB_LOCK(KeyBody->KeyControlBlock);
1085 
1086  /* Do the insert */
1087  InsertTailList(&KeyBody->KeyControlBlock->KeyBodyListHead,
1088  &KeyBody->KeyBodyList);
1089 
1090  /* Check if we did a manual lock */
1093  {
1094  /* Release the lock */
1095  CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1096  }
1097 }
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
#define CMP_ENLIST_KCB_LOCKED_EXCLUSIVE
Definition: cm.h:103
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define CMP_ENLIST_KCB_LOCKED_SHARED
Definition: cm.h:102
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102

Referenced by CmpCreateRegistryRoot(), CmpDoCreateChild(), and CmpDoOpen().

◆ InitializeKCBKeyBodyList()

VOID NTAPI InitializeKCBKeyBodyList ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 641 of file cmkcbncb.c.

642 {
643  /* Initialize the list */
644  InitializeListHead(&Kcb->KeyBodyListHead);
645 
646  /* Clear the bodies */
647  Kcb->KeyBodyArray[0] =
648  Kcb->KeyBodyArray[1] =
649  Kcb->KeyBodyArray[2] =
650  Kcb->KeyBodyArray[3] = NULL;
651 }
smooth NULL
Definition: ftsmooth.c:416
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

Referenced by CmpCreateKeyControlBlock().

Variable Documentation

◆ CmpCacheTable

◆ CmpHashTableSize

ULONG CmpHashTableSize = 2048

Definition at line 17 of file cmkcbncb.c.

Referenced by CmpEnumerateOpenSubKeys(), and CmpInitializeCache().

◆ CmpNameCacheTable