ReactOS 0.4.15-dev-5672-gf73ac17
cm.h File Reference
#include <cmlib.h>
#include <cmreslist.h>
#include "cmboot.h"
#include "cm_x.h"
Include dependency graph for cm.h:

Go to the source code of this file.

Classes

struct  _CM_KEY_HASH
 
struct  _CM_KEY_HASH_TABLE_ENTRY
 
struct  _CM_NAME_HASH
 
struct  _CM_NAME_HASH_TABLE_ENTRY
 
struct  _CM_KEY_SECURITY_CACHE
 
struct  _CM_KEY_SECURITY_CACHE_ENTRY
 
struct  _CACHED_CHILD_LIST
 
struct  _CM_INDEX_HINT_BLOCK
 
struct  _CM_KEY_BODY
 
struct  _CM_NAME_CONTROL_BLOCK
 
struct  _CM_KEY_CONTROL_BLOCK
 
struct  _CM_NOTIFY_BLOCK
 
struct  _CM_CELL_REMAP_BLOCK
 
struct  _CM_ALLOC_PAGE
 
struct  _CM_DELAY_ALLOC
 
struct  _CM_DELAYED_CLOSE_ENTRY
 
struct  _CM_DELAY_DEREF_KCB_ITEM
 
struct  _CM_CACHED_VALUE_INDEX
 
struct  _CM_CACHED_VALUE
 
struct  _HIVE_LIST_ENTRY
 
struct  _CM_PARSE_CONTEXT
 
struct  _CMP_MF_TYPE
 
struct  _CM_SYSTEM_CONTROL_VECTOR
 
struct  _KEY_VALUE_INFORMATION
 
struct  _KEY_INFORMATION
 

Macros

#define _CM_DEBUG_   0x00
 
#define CM_HANDLE_DEBUG   0x01
 
#define CM_NAMESPACE_DEBUG   0x02
 
#define CM_SECURITY_DEBUG   0x04
 
#define CM_REFERENCE_DEBUG   0x08
 
#define CM_CALLBACK_DEBUG   0x10
 
#define CMTRACE(x, fmt, ...)   DPRINT(fmt, ##__VA_ARGS__)
 
#define CM_KCB_SIGNATURE   'bKmC'
 
#define CM_KCB_INVALID_SIGNATURE   '4FmC'
 
#define CM_KCB_NO_SUBKEY   0x01
 
#define CM_KCB_SUBKEY_ONE   0x02
 
#define CM_KCB_SUBKEY_HINT   0x04
 
#define CM_KCB_SYM_LINK_FOUND   0x08
 
#define CM_KCB_KEY_NON_EXIST   0x10
 
#define CM_KCB_NO_DELAY_CLOSE   0x20
 
#define CM_KCB_INVALID_CACHED_INFO   0x40
 
#define CM_KCB_READ_ONLY_KEY   0x80
 
#define CM_KEY_BODY_TYPE   0x6B793032
 
#define CMP_MAX_CALLBACKS   100
 
#define CMP_HASH_IRRATIONAL   314159269
 
#define CMP_HASH_PRIME   1000000007
 
#define CMP_CREATE_FAKE_KCB   0x1
 
#define CMP_LOCK_HASHES_FOR_KCB   0x2
 
#define CMP_CREATE_KCB_KCB_LOCKED   0x2
 
#define CMP_OPEN_KCB_NO_CREATE   0x4
 
#define CMP_ENLIST_KCB_LOCKED_SHARED   0x1
 
#define CMP_ENLIST_KCB_LOCKED_EXCLUSIVE   0x2
 
#define CMP_UNLOCK_KCB_LOCKED   0x1
 
#define CMP_UNLOCK_REGISTRY_LOCKED   0x2
 
#define MAXIMUM_CACHED_DATA   (2 * PAGE_SIZE)
 
#define CM_NUMBER_OF_MACHINE_HIVES   6
 
#define CM_KCBS_PER_PAGE    ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_KEY_CONTROL_BLOCK))
 
#define CM_DELAYS_PER_PAGE    ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_DELAY_ALLOC))
 

Typedefs

typedef enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
 
typedef struct _CM_KEY_HASH CM_KEY_HASH
 
typedef struct _CM_KEY_HASHPCM_KEY_HASH
 
typedef struct _CM_KEY_HASH_TABLE_ENTRY CM_KEY_HASH_TABLE_ENTRY
 
typedef struct _CM_KEY_HASH_TABLE_ENTRYPCM_KEY_HASH_TABLE_ENTRY
 
typedef struct _CM_NAME_HASH CM_NAME_HASH
 
typedef struct _CM_NAME_HASHPCM_NAME_HASH
 
typedef struct _CM_NAME_HASH_TABLE_ENTRY CM_NAME_HASH_TABLE_ENTRY
 
typedef struct _CM_NAME_HASH_TABLE_ENTRYPCM_NAME_HASH_TABLE_ENTRY
 
typedef struct _CM_KEY_SECURITY_CACHE CM_KEY_SECURITY_CACHE
 
typedef struct _CM_KEY_SECURITY_CACHEPCM_KEY_SECURITY_CACHE
 
typedef struct _CM_KEY_SECURITY_CACHE_ENTRY CM_KEY_SECURITY_CACHE_ENTRY
 
typedef struct _CM_KEY_SECURITY_CACHE_ENTRYPCM_KEY_SECURITY_CACHE_ENTRY
 
typedef struct _CACHED_CHILD_LIST CACHED_CHILD_LIST
 
typedef struct _CACHED_CHILD_LISTPCACHED_CHILD_LIST
 
typedef struct _CM_INDEX_HINT_BLOCK CM_INDEX_HINT_BLOCK
 
typedef struct _CM_INDEX_HINT_BLOCKPCM_INDEX_HINT_BLOCK
 
typedef struct _CM_KEY_BODY CM_KEY_BODY
 
typedef struct _CM_KEY_BODYPCM_KEY_BODY
 
typedef struct _CM_NAME_CONTROL_BLOCK CM_NAME_CONTROL_BLOCK
 
typedef struct _CM_NAME_CONTROL_BLOCKPCM_NAME_CONTROL_BLOCK
 
typedef struct _CM_KEY_CONTROL_BLOCK CM_KEY_CONTROL_BLOCK
 
typedef struct _CM_KEY_CONTROL_BLOCKPCM_KEY_CONTROL_BLOCK
 
typedef struct _CM_NOTIFY_BLOCK CM_NOTIFY_BLOCK
 
typedef struct _CM_NOTIFY_BLOCKPCM_NOTIFY_BLOCK
 
typedef struct _CM_CELL_REMAP_BLOCK CM_CELL_REMAP_BLOCK
 
typedef struct _CM_CELL_REMAP_BLOCKPCM_CELL_REMAP_BLOCK
 
typedef struct _CM_ALLOC_PAGE CM_ALLOC_PAGE
 
typedef struct _CM_ALLOC_PAGEPCM_ALLOC_PAGE
 
typedef struct _CM_DELAY_ALLOC CM_DELAY_ALLOC
 
typedef struct _CM_DELAY_ALLOCPCM_DELAY_ALLOC
 
typedef struct _CM_DELAYED_CLOSE_ENTRY CM_DELAYED_CLOSE_ENTRY
 
typedef struct _CM_DELAYED_CLOSE_ENTRYPCM_DELAYED_CLOSE_ENTRY
 
typedef struct _CM_DELAY_DEREF_KCB_ITEM CM_DELAY_DEREF_KCB_ITEM
 
typedef struct _CM_DELAY_DEREF_KCB_ITEMPCM_DELAY_DEREF_KCB_ITEM
 
typedef struct _CM_CACHED_VALUE_INDEX CM_CACHED_VALUE_INDEX
 
typedef struct _CM_CACHED_VALUE_INDEXPCM_CACHED_VALUE_INDEX
 
typedef struct _CM_CACHED_VALUE CM_CACHED_VALUE
 
typedef struct _CM_CACHED_VALUEPCM_CACHED_VALUE
 
typedef struct _HIVE_LIST_ENTRY HIVE_LIST_ENTRY
 
typedef struct _HIVE_LIST_ENTRYPHIVE_LIST_ENTRY
 
typedef struct _CM_PARSE_CONTEXT CM_PARSE_CONTEXT
 
typedef struct _CM_PARSE_CONTEXTPCM_PARSE_CONTEXT
 
typedef struct _CMP_MF_TYPE CMP_MF_TYPE
 
typedef struct _CMP_MF_TYPEPCMP_MF_TYPE
 
typedef struct _CM_SYSTEM_CONTROL_VECTOR CM_SYSTEM_CONTROL_VECTOR
 
typedef struct _CM_SYSTEM_CONTROL_VECTORPCM_SYSTEM_CONTROL_VECTOR
 
typedef struct _KEY_VALUE_INFORMATION KEY_VALUE_INFORMATION
 
typedef struct _KEY_VALUE_INFORMATIONPKEY_VALUE_INFORMATION
 
typedef struct _KEY_INFORMATION KEY_INFORMATION
 
typedef struct _KEY_INFORMATIONPKEY_INFORMATION
 

Enumerations

enum  _VALUE_SEARCH_RETURN_TYPE { SearchSuccess , SearchNeedExclusiveLock , SearchFail }
 

Functions

NTSTATUS CmiCallRegisteredCallbacks (IN REG_NOTIFY_CLASS Argument1, IN PVOID Argument2)
 
VOID NTAPI CmpInitHiveViewList (IN PCMHIVE Hive)
 
VOID NTAPI CmpDestroyHiveViewList (IN PCMHIVE Hive)
 
VOID NTAPI CmpInitSecurityCache (IN PCMHIVE Hive)
 
VOID NTAPI CmpDestroySecurityCache (IN PCMHIVE Hive)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpFindValueByNameFromCache (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCUNICODE_STRING Name, OUT PCM_CACHED_VALUE **CachedValue, OUT ULONG *Index, OUT PCM_KEY_VALUE *Value, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpQueryKeyValueData (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCM_KEY_VALUE ValueKey, IN BOOLEAN ValueIsCached, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength, OUT PNTSTATUS Status)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache (IN PCM_KEY_CONTROL_BLOCK Kcb, OUT PCELL_DATA *CellData, OUT BOOLEAN *IndexIsCached, OUT PHCELL_INDEX ValueListToRelease)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueKeyFromCache (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCELL_DATA CellData, IN ULONG Index, OUT PCM_CACHED_VALUE **CachedValue, OUT PCM_KEY_VALUE *Value, IN BOOLEAN IndexIsCached, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpCompareNewValueDataAgainstKCBCache (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
 
ULONG NTAPI CmCheckRegistry (IN PCMHIVE Hive, IN ULONG Flags)
 
BOOLEAN NTAPI CmpGetHiveName (IN PCMHIVE Hive, OUT PUNICODE_STRING HiveName)
 
NTSTATUS NTAPI CmpAddToHiveFileList (IN PCMHIVE Hive)
 
VOID NTAPI CmpRemoveFromHiveFileList (IN PCMHIVE Hive)
 
VOID NTAPI CmpSetGlobalQuotaAllowed (VOID)
 
VOID NTAPI CmpReportNotify (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PHHIVE Hive, IN HCELL_INDEX Cell, IN ULONG Filter)
 
VOID NTAPI CmpFlushNotify (IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
 
VOID NTAPI CmpInitCallback (VOID)
 
VOID NTAPI CmpInitializeCache (VOID)
 
VOID NTAPI CmpInitCmPrivateDelayAlloc (VOID)
 
VOID NTAPI CmpInitCmPrivateAlloc (VOID)
 
VOID NTAPI CmpInitDelayDerefKCBEngine (VOID)
 
VOID NTAPI CmpCloseKeyObject (IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ACCESS_MASK GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
 
VOID NTAPI CmpDeleteKeyObject (IN PVOID Object)
 
NTSTATUS NTAPI CmpParseKey (IN PVOID ParseObject, IN PVOID ObjectType, IN OUT PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
 
NTSTATUS NTAPI CmpSecurityMethod (IN PVOID Object, IN SECURITY_OPERATION_CODE OperationType, IN PSECURITY_INFORMATION SecurityInformation, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG CapturedLength, IN OUT PSECURITY_DESCRIPTOR *ObjectSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
 
NTSTATUS NTAPI CmpQueryKeyName (IN PVOID Object, IN BOOLEAN HasObjectName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength, IN KPROCESSOR_MODE AccessMode)
 
NTSTATUS NTAPI CmpInitializeHive (OUT PCMHIVE *CmHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags)
 
NTSTATUS NTAPI CmpDestroyHive (IN PCMHIVE CmHive)
 
PSECURITY_DESCRIPTOR NTAPI CmpHiveRootSecurityDescriptor (VOID)
 
NTSTATUS NTAPI CmpLinkHiveToMaster (IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE CmHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
 
NTSTATUS NTAPI CmpOpenHiveFiles (IN PCUNICODE_STRING BaseName, IN PCWSTR Extension OPTIONAL, OUT PHANDLE Primary, OUT PHANDLE Log, OUT PULONG PrimaryDisposition, OUT PULONG LogDisposition, IN BOOLEAN CreateAllowed, IN BOOLEAN MarkAsSystemHive, IN BOOLEAN NoBuffering, OUT PULONG ClusterSize OPTIONAL)
 
VOID NTAPI CmpCloseHiveFiles (IN PCMHIVE Hive)
 
NTSTATUS NTAPI CmpInitHiveFromFile (IN PCUNICODE_STRING HiveName, IN ULONG HiveFlags, OUT PCMHIVE *Hive, IN OUT PBOOLEAN New, IN ULONG CheckFlags)
 
VOID NTAPI CmpInitializeHiveList (VOID)
 
BOOLEAN NTAPI CmpTestRegistryLockExclusive (VOID)
 
BOOLEAN NTAPI CmpTestRegistryLock (VOID)
 
VOID NTAPI CmpLockRegistryExclusive (VOID)
 
VOID NTAPI CmpLockRegistry (VOID)
 
VOID NTAPI CmpUnlockRegistry (VOID)
 
VOID NTAPI CmpLockHiveFlusherExclusive (IN PCMHIVE Hive)
 
VOID NTAPI CmpLockHiveFlusherShared (IN PCMHIVE Hive)
 
BOOLEAN NTAPI CmpTestHiveFlusherLockExclusive (IN PCMHIVE Hive)
 
BOOLEAN NTAPI CmpTestHiveFlusherLockShared (IN PCMHIVE Hive)
 
VOID NTAPI CmpUnlockHiveFlusher (IN PCMHIVE Hive)
 
PVOID NTAPI CmpAllocateDelayItem (VOID)
 
VOID NTAPI CmpFreeDelayItem (PVOID Entry)
 
VOID NTAPI CmpDelayDerefKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpAddToDelayedClose (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
 
VOID NTAPI CmpArmDelayedCloseTimer (VOID)
 
VOID NTAPI CmpRemoveFromDelayedClose (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpInitializeDelayedCloseTable (VOID)
 
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)
 
PCM_KEY_CONTROL_BLOCK NTAPI CmpAllocateKeyControlBlock (VOID)
 
VOID NTAPI CmpFreeKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpRemoveKeyControlBlock (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)
 
PUNICODE_STRING NTAPI CmpConstructName (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
BOOLEAN NTAPI CmpReferenceKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI CmpDereferenceKeyControlBlockWithLock (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
 
VOID NTAPI CmpDereferenceKeyControlBlock (IN PCM_KEY_CONTROL_BLOCK Kcb)
 
VOID NTAPI EnlistKeyBodyWithKCB (IN PCM_KEY_BODY KeyObject, IN ULONG Flags)
 
VOID NTAPI DelistKeyBodyFromKCB (IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
 
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey (IN ULONG ConvKey1, IN ULONG ConvKey2)
 
VOID NTAPI CmpReleaseTwoKcbLockByKey (IN ULONG ConvKey1, IN ULONG ConvKey2)
 
VOID NTAPI CmpFlushNotifiesOnKeyBodyList (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
 
BOOLEAN NTAPI CmpGetNextName (IN OUT PUNICODE_STRING RemainingName, OUT PUNICODE_STRING NextName, OUT PBOOLEAN LastName)
 
BOOLEAN NTAPI CmpDoFlushAll (IN BOOLEAN ForceFlush)
 
VOID NTAPI CmpShutdownWorkers (VOID)
 
VOID NTAPI CmpCmdInit (IN BOOLEAN SetupBoot)
 
NTSTATUS NTAPI CmpCmdHiveOpen (IN POBJECT_ATTRIBUTES FileAttributes, IN PSECURITY_CLIENT_CONTEXT ImpersonationContext, IN OUT PBOOLEAN Allocate, OUT PCMHIVE *NewHive, IN ULONG CheckFlags)
 
VOID NTAPI CmpLazyFlush (VOID)
 
NTSTATUS NTAPI CmpDoCreate (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
 
NTSTATUS NTAPI CmpCreateLinkNode (IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PACCESS_STATE AccessState, IN UNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN ULONG CreateOptions, IN PCM_PARSE_CONTEXT Context, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
 
VOID NTAPI CmGetSystemControlValues (IN PVOID SystemHiveData, IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
 
NTSTATUS NTAPI CmpSaveBootControlSet (IN USHORT ControlSet)
 
NTSTATUS NTAPI CmpInitializeRegistryNode (IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE NodeHandle, OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PUSHORT DeviceIndexTable)
 
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI CmpInitializeHardwareConfiguration (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI CmpCreateEvent (IN EVENT_TYPE EventType, OUT PHANDLE EventHandle, OUT PKEVENT *Event)
 
PVOID NTAPI CmpAllocate (IN SIZE_T Size, IN BOOLEAN Paged, IN ULONG Tag)
 
VOID NTAPI CmpFree (IN PVOID Ptr, IN ULONG Quota)
 
BOOLEAN NTAPI CmpFileRead (IN PHHIVE RegistryHive, IN ULONG FileType, IN OUT PULONG FileOffset, OUT PVOID Buffer, IN SIZE_T BufferLength)
 
BOOLEAN NTAPI CmpFileWrite (IN PHHIVE RegistryHive, IN ULONG FileType, IN OUT PULONG FileOffset, IN PVOID Buffer, IN SIZE_T BufferLength)
 
BOOLEAN NTAPI CmpFileSetSize (IN PHHIVE RegistryHive, IN ULONG FileType, IN ULONG FileSize, IN ULONG OldFileSize)
 
BOOLEAN NTAPI CmpFileFlush (IN PHHIVE RegistryHive, IN ULONG FileType, IN OUT PLARGE_INTEGER FileOffset, IN ULONG Length)
 
NTSTATUS NTAPI CmEnumerateValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmSetValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
 
NTSTATUS NTAPI CmQueryKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN KEY_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmEnumerateKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Index, IN KEY_INFORMATION_CLASS KeyInformationClass, IN PVOID KeyInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmDeleteKey (IN PCM_KEY_BODY KeyBody)
 
NTSTATUS NTAPI CmFlushKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN EclusiveLock)
 
NTSTATUS NTAPI CmDeleteValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName)
 
NTSTATUS NTAPI CmQueryValueKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN UNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
 
NTSTATUS NTAPI CmLoadKey (IN POBJECT_ATTRIBUTES TargetKey, IN POBJECT_ATTRIBUTES SourceFile, IN ULONG Flags, IN PCM_KEY_BODY KeyBody)
 
NTSTATUS NTAPI CmUnloadKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN ULONG Flags)
 
ULONG NTAPI CmpEnumerateOpenSubKeys (IN PCM_KEY_CONTROL_BLOCK RootKcb, IN BOOLEAN RemoveEmptyCacheEntries, IN BOOLEAN DereferenceOpenedEntries)
 
HCELL_INDEX NTAPI CmpCopyCell (IN PHHIVE SourceHive, IN HCELL_INDEX SourceCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType)
 
NTSTATUS NTAPI CmpDeepCopyKey (IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
 
NTSTATUS NTAPI CmSaveKey (IN PCM_KEY_CONTROL_BLOCK Kcb, IN HANDLE FileHandle, IN ULONG Flags)
 
NTSTATUS NTAPI CmSaveMergedKeys (IN PCM_KEY_CONTROL_BLOCK HighKcb, IN PCM_KEY_CONTROL_BLOCK LowKcb, IN HANDLE FileHandle)
 
BOOLEAN NTAPI CmInitSystem1 (VOID)
 
VOID NTAPI CmShutdownSystem (VOID)
 
VOID NTAPI CmSetLazyFlushState (IN BOOLEAN Enable)
 
VOID NTAPI CmpSetVersionData (VOID)
 
PUNICODE_STRING *NTAPI CmGetSystemDriverList (VOID)
 

Variables

ULONG CmpTraceLevel
 
BOOLEAN CmpSpecialBootCondition
 
BOOLEAN CmpFlushOnLockRelease
 
BOOLEAN CmpShareSystemHives
 
BOOLEAN CmpMiniNTBoot
 
BOOLEAN CmpNoVolatileCreates
 
EX_PUSH_LOCK CmpHiveListHeadLock
 
EX_PUSH_LOCK CmpLoadHiveLock
 
LIST_ENTRY CmpHiveListHead
 
POBJECT_TYPE CmpKeyObjectType
 
ERESOURCE CmpRegistryLock
 
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
 
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
 
KGUARDED_MUTEX CmpDelayedCloseTableLock
 
CMHIVE CmControlHive
 
WCHAR CmDefaultLanguageId []
 
ULONG CmDefaultLanguageIdLength
 
ULONG CmDefaultLanguageIdType
 
WCHAR CmInstallUILanguageId []
 
ULONG CmInstallUILanguageIdLength
 
ULONG CmInstallUILanguageIdType
 
ULONG CmNtGlobalFlag
 
LANGID PsInstallUILanguageId
 
LANGID PsDefaultUILanguageId
 
CM_SYSTEM_CONTROL_VECTOR CmControlVector []
 
ULONG CmpConfigurationAreaSize
 
PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData
 
UNICODE_STRING CmTypeName []
 
UNICODE_STRING CmClassName []
 
CMP_MF_TYPE CmpMultifunctionTypes []
 
USHORT CmpUnknownBusCount
 
ULONG CmpTypeCount [MaximumType+1]
 
HIVE_LIST_ENTRY CmpMachineHiveList []
 
UNICODE_STRING CmSymbolicLinkValueName
 
UNICODE_STRING CmpSystemStartOptions
 
UNICODE_STRING CmpLoadOptions
 
BOOLEAN CmSelfHeal
 
BOOLEAN CmpSelfHeal
 
ULONG CmpBootType
 
HANDLE CmpRegistryRootHandle
 
BOOLEAN ExpInTextModeSetup
 
BOOLEAN InitIsWinPEMode
 
ULONG CmpHashTableSize
 
ULONG CmpDelayedCloseSize
 
ULONG CmpDelayedCloseIndex
 
BOOLEAN CmpNoWrite
 
BOOLEAN CmpForceForceFlush
 
BOOLEAN CmpWasSetupBoot
 
BOOLEAN CmpProfileLoaded
 
PCMHIVE CmiVolatileHive
 
LIST_ENTRY CmiKeyObjectListHead
 
BOOLEAN CmpHoldLazyFlush
 

Macro Definition Documentation

◆ _CM_DEBUG_

#define _CM_DEBUG_   0x00

Definition at line 18 of file cm.h.

◆ CM_CALLBACK_DEBUG

#define CM_CALLBACK_DEBUG   0x10

Definition at line 27 of file cm.h.

◆ CM_DELAYS_PER_PAGE

#define CM_DELAYS_PER_PAGE    ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_DELAY_ALLOC))

Definition at line 119 of file cm.h.

◆ CM_HANDLE_DEBUG

#define CM_HANDLE_DEBUG   0x01

Definition at line 23 of file cm.h.

◆ CM_KCB_INVALID_CACHED_INFO

#define CM_KCB_INVALID_CACHED_INFO   0x40

Definition at line 58 of file cm.h.

◆ CM_KCB_INVALID_SIGNATURE

#define CM_KCB_INVALID_SIGNATURE   '4FmC'

Definition at line 47 of file cm.h.

◆ CM_KCB_KEY_NON_EXIST

#define CM_KCB_KEY_NON_EXIST   0x10

Definition at line 56 of file cm.h.

◆ CM_KCB_NO_DELAY_CLOSE

#define CM_KCB_NO_DELAY_CLOSE   0x20

Definition at line 57 of file cm.h.

◆ CM_KCB_NO_SUBKEY

#define CM_KCB_NO_SUBKEY   0x01

Definition at line 52 of file cm.h.

◆ CM_KCB_READ_ONLY_KEY

#define CM_KCB_READ_ONLY_KEY   0x80

Definition at line 59 of file cm.h.

◆ CM_KCB_SIGNATURE

#define CM_KCB_SIGNATURE   'bKmC'

Definition at line 46 of file cm.h.

◆ CM_KCB_SUBKEY_HINT

#define CM_KCB_SUBKEY_HINT   0x04

Definition at line 54 of file cm.h.

◆ CM_KCB_SUBKEY_ONE

#define CM_KCB_SUBKEY_ONE   0x02

Definition at line 53 of file cm.h.

◆ CM_KCB_SYM_LINK_FOUND

#define CM_KCB_SYM_LINK_FOUND   0x08

Definition at line 55 of file cm.h.

◆ CM_KCBS_PER_PAGE

#define CM_KCBS_PER_PAGE    ((PAGE_SIZE - FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage)) / sizeof(CM_KEY_CONTROL_BLOCK))

Definition at line 117 of file cm.h.

◆ CM_KEY_BODY_TYPE

#define CM_KEY_BODY_TYPE   0x6B793032

Definition at line 64 of file cm.h.

◆ CM_NAMESPACE_DEBUG

#define CM_NAMESPACE_DEBUG   0x02

Definition at line 24 of file cm.h.

◆ CM_NUMBER_OF_MACHINE_HIVES

#define CM_NUMBER_OF_MACHINE_HIVES   6

Definition at line 112 of file cm.h.

◆ CM_REFERENCE_DEBUG

#define CM_REFERENCE_DEBUG   0x08

Definition at line 26 of file cm.h.

◆ CM_SECURITY_DEBUG

#define CM_SECURITY_DEBUG   0x04

Definition at line 25 of file cm.h.

◆ CMP_CREATE_FAKE_KCB

#define CMP_CREATE_FAKE_KCB   0x1

Definition at line 83 of file cm.h.

◆ CMP_CREATE_KCB_KCB_LOCKED

#define CMP_CREATE_KCB_KCB_LOCKED   0x2

Definition at line 89 of file cm.h.

◆ CMP_ENLIST_KCB_LOCKED_EXCLUSIVE

#define CMP_ENLIST_KCB_LOCKED_EXCLUSIVE   0x2

Definition at line 96 of file cm.h.

◆ CMP_ENLIST_KCB_LOCKED_SHARED

#define CMP_ENLIST_KCB_LOCKED_SHARED   0x1

Definition at line 95 of file cm.h.

◆ CMP_HASH_IRRATIONAL

#define CMP_HASH_IRRATIONAL   314159269

Definition at line 77 of file cm.h.

◆ CMP_HASH_PRIME

#define CMP_HASH_PRIME   1000000007

Definition at line 78 of file cm.h.

◆ CMP_LOCK_HASHES_FOR_KCB

#define CMP_LOCK_HASHES_FOR_KCB   0x2

Definition at line 84 of file cm.h.

◆ CMP_MAX_CALLBACKS

#define CMP_MAX_CALLBACKS   100

Definition at line 72 of file cm.h.

◆ CMP_OPEN_KCB_NO_CREATE

#define CMP_OPEN_KCB_NO_CREATE   0x4

Definition at line 90 of file cm.h.

◆ CMP_UNLOCK_KCB_LOCKED

#define CMP_UNLOCK_KCB_LOCKED   0x1

Definition at line 101 of file cm.h.

◆ CMP_UNLOCK_REGISTRY_LOCKED

#define CMP_UNLOCK_REGISTRY_LOCKED   0x2

Definition at line 102 of file cm.h.

◆ CMTRACE

#define CMTRACE (   x,
  fmt,
  ... 
)    DPRINT(fmt, ##__VA_ARGS__)

Definition at line 40 of file cm.h.

◆ MAXIMUM_CACHED_DATA

#define MAXIMUM_CACHED_DATA   (2 * PAGE_SIZE)

Definition at line 107 of file cm.h.

Typedef Documentation

◆ CACHED_CHILD_LIST

◆ CM_ALLOC_PAGE

◆ CM_CACHED_VALUE

◆ CM_CACHED_VALUE_INDEX

◆ CM_CELL_REMAP_BLOCK

◆ CM_DELAY_ALLOC

◆ CM_DELAY_DEREF_KCB_ITEM

◆ CM_DELAYED_CLOSE_ENTRY

◆ CM_INDEX_HINT_BLOCK

◆ CM_KEY_BODY

◆ CM_KEY_CONTROL_BLOCK

◆ CM_KEY_HASH

◆ CM_KEY_HASH_TABLE_ENTRY

◆ CM_KEY_SECURITY_CACHE

◆ CM_KEY_SECURITY_CACHE_ENTRY

◆ CM_NAME_CONTROL_BLOCK

◆ CM_NAME_HASH

◆ CM_NAME_HASH_TABLE_ENTRY

◆ CM_NOTIFY_BLOCK

◆ CM_PARSE_CONTEXT

◆ CM_SYSTEM_CONTROL_VECTOR

◆ CMP_MF_TYPE

◆ HIVE_LIST_ENTRY

◆ KEY_INFORMATION

◆ KEY_VALUE_INFORMATION

◆ PCACHED_CHILD_LIST

◆ PCM_ALLOC_PAGE

◆ PCM_CACHED_VALUE

◆ PCM_CACHED_VALUE_INDEX

◆ PCM_CELL_REMAP_BLOCK

◆ PCM_DELAY_ALLOC

◆ PCM_DELAY_DEREF_KCB_ITEM

◆ PCM_DELAYED_CLOSE_ENTRY

◆ PCM_INDEX_HINT_BLOCK

◆ PCM_KEY_BODY

◆ PCM_KEY_CONTROL_BLOCK

◆ PCM_KEY_HASH

◆ PCM_KEY_HASH_TABLE_ENTRY

◆ PCM_KEY_SECURITY_CACHE

◆ PCM_KEY_SECURITY_CACHE_ENTRY

◆ PCM_NAME_CONTROL_BLOCK

◆ PCM_NAME_HASH

◆ PCM_NAME_HASH_TABLE_ENTRY

◆ PCM_NOTIFY_BLOCK

◆ PCM_PARSE_CONTEXT

◆ PCM_SYSTEM_CONTROL_VECTOR

◆ PCMP_MF_TYPE

◆ PHIVE_LIST_ENTRY

◆ PKEY_INFORMATION

◆ PKEY_VALUE_INFORMATION

◆ VALUE_SEARCH_RETURN_TYPE

Enumeration Type Documentation

◆ _VALUE_SEARCH_RETURN_TYPE

Enumerator
SearchSuccess 
SearchNeedExclusiveLock 
SearchFail 

Definition at line 125 of file cm.h.

126{
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
@ SearchSuccess
Definition: cm.h:127
@ SearchNeedExclusiveLock
Definition: cm.h:128
@ SearchFail
Definition: cm.h:129

Function Documentation

◆ CmCheckRegistry()

ULONG NTAPI CmCheckRegistry ( IN PCMHIVE  Hive,
IN ULONG  Flags 
)

Definition at line 21 of file cmcheck.c.

23{
24 /* FIXME: HACK! */
25 DPRINT1("CmCheckRegistry(0x%p, %lu) is UNIMPLEMENTED!\n", RegistryHive, Flags);
26 return 0;
27}
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by CmpInitializeHive().

◆ CmDeleteKey()

NTSTATUS NTAPI CmDeleteKey ( IN PCM_KEY_BODY  KeyBody)

Definition at line 1824 of file cmapi.c.

1825{
1827 PHHIVE Hive;
1829 HCELL_INDEX Cell, ParentCell;
1831
1832 /* Acquire hive lock */
1834
1835 /* Get the kcb */
1836 Kcb = KeyBody->KeyControlBlock;
1837
1838 /* Don't allow deleting the root */
1839 if (!Kcb->ParentKcb)
1840 {
1841 /* Fail */
1843 return STATUS_CANNOT_DELETE;
1844 }
1845
1846 /* Lock parent and child */
1848
1849 /* Check if we're already being deleted */
1850 if (Kcb->Delete)
1851 {
1852 /* Don't do it twice */
1854 goto Quickie;
1855 }
1856
1857 /* Get the hive and node */
1858 Hive = Kcb->KeyHive;
1859 Cell = Kcb->KeyCell;
1860
1861 /* Lock flushes */
1863
1864 /* Get the key node */
1865 Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1866 ASSERT(Node);
1867
1868 /* Sanity check */
1869 ASSERT(Node->Flags == Kcb->Flags);
1870
1871 /* Check if we don't have any children */
1872 if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) &&
1873 !(Node->Flags & KEY_NO_DELETE))
1874 {
1875 /* Send notification to registered callbacks */
1876 CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME);
1877
1878 /* Get the parent and free the cell */
1879 ParentCell = Node->Parent;
1880 Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
1881 if (NT_SUCCESS(Status))
1882 {
1883 /* Flush any notifications */
1885
1886 /* Clean up information we have on the subkey */
1888
1889 /* Get the parent node */
1890 Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
1891 if (Parent)
1892 {
1893 /* Update the maximum name length */
1894 Kcb->ParentKcb->KcbMaxNameLen = (USHORT)Parent->MaxNameLen;
1895
1896 /* Make sure we're dirty */
1897 ASSERT(HvIsCellDirty(Hive, ParentCell));
1898
1899 /* Update the write time */
1900 KeQuerySystemTime(&Parent->LastWriteTime);
1901 Kcb->ParentKcb->KcbLastWriteTime = Parent->LastWriteTime;
1902
1903 /* Release the cell */
1904 HvReleaseCell(Hive, ParentCell);
1905 }
1906
1907 /* Set the KCB in delete mode and remove it */
1908 Kcb->Delete = TRUE;
1910
1911 /* Clear the cell */
1912 Kcb->KeyCell = HCELL_NIL;
1913 }
1914 }
1915 else
1916 {
1917 /* Fail */
1919 }
1920
1921 /* Release the cell */
1922 HvReleaseCell(Hive, Cell);
1923
1924 /* Release flush lock */
1926
1927 /* Release the KCB locks */
1928Quickie:
1929 CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
1930
1931 /* Release hive lock */
1933 return Status;
1934}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx 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:732
LONG NTSTATUS
Definition: precomp.h:26
struct _CM_KEY_NODE * PCM_KEY_NODE
#define KEY_NO_DELETE
Definition: cmdata.h:33
VOID NTAPI CmpFlushNotifiesOnKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeld)
Definition: cmkcbncb.c:1139
VOID NTAPI CmpCleanUpSubKeyInfo(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:517
VOID NTAPI CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:306
NTSTATUS NTAPI CmpFreeKeyByCell(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN BOOLEAN Unlink)
Definition: cmkeydel.c:159
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:384
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:153
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:381
VOID NTAPI CmpReportNotify(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PHHIVE Hive, IN HCELL_INDEX Cell, IN ULONG Filter)
Definition: cmnotify.c:19
VOID NTAPI CmpUnlockRegistry(VOID)
Definition: cmsysini.c:1944
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:1967
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:1996
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1858
VOID NTAPI CmpLockHiveFlusherShared(IN PCMHIVE Hive)
Definition: cmsysini.c:1905
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:1916
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union node Node
Definition: types.h:1255
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
Status
Definition: gdiplustypes.h:25
@ Volatile
Definition: hivedata.h:103
@ Stable
Definition: hivedata.h:102
#define HCELL_NIL
Definition: hivedata.h:85
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define ASSERT(a)
Definition: mode.c:44
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cmlib.h:245
PHHIVE KeyHive
Definition: cm.h:270
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:274
HCELL_INDEX KeyCell
Definition: cm.h:271
Definition: dlist.c:348
#define REG_NOTIFY_CHANGE_NAME
Definition: winreg.h:38

Referenced by NtDeleteKey().

◆ CmDeleteValueKey()

NTSTATUS NTAPI CmDeleteValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN UNICODE_STRING  ValueName 
)

Definition at line 916 of file cmapi.c.

918{
920 PHHIVE Hive;
922 HCELL_INDEX ChildCell, Cell;
925 ULONG ChildIndex;
927
928 /* Acquire hive lock */
930
931 /* Lock KCB exclusively */
933
934 /* Don't touch deleted keys */
935 if (Kcb->Delete)
936 {
937 /* Undo everything */
940 return STATUS_KEY_DELETED;
941 }
942
943 /* Get the hive and the cell index */
944 Hive = Kcb->KeyHive;
945 Cell = Kcb->KeyCell;
946
947 /* Lock flushes */
949
950 /* Get the parent key node */
951 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
952 ASSERT(Parent);
953
954 /* Get the value list and check if it has any entries */
955 ChildList = &Parent->ValueList;
956 if (ChildList->Count)
957 {
958 /* Try to find this value */
960 ChildList,
961 &ValueName,
962 &ChildIndex,
963 &ChildCell);
964 if (!Result)
965 {
966 /* Fail */
968 goto Quickie;
969 }
970
971 /* Value not found, return error */
972 if (ChildCell == HCELL_NIL) goto Quickie;
973
974 /* We found the value, mark all relevant cells dirty */
975 if (!((HvMarkCellDirty(Hive, Cell, FALSE)) &&
976 (HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE)) &&
977 (HvMarkCellDirty(Hive, ChildCell, FALSE))))
978 {
979 /* Not enough log space, fail */
981 goto Quickie;
982 }
983
984 /* Get the key value */
985 Value = (PCM_KEY_VALUE)HvGetCell(Hive, ChildCell);
986 ASSERT(Value);
987
988 /* Mark it and all related data as dirty */
989 if (!CmpMarkValueDataDirty(Hive, Value))
990 {
991 /* Not enough log space, fail */
993 goto Quickie;
994 }
995
996 /* Sanity checks */
997 ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
998 ASSERT(HvIsCellDirty(Hive, ChildCell));
999
1000 /* Remove the value from the child list */
1001 Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList);
1002 if (!NT_SUCCESS(Status))
1003 {
1004 /* Set known error */
1006 goto Quickie;
1007 }
1008
1009 /* Remove the value and its data itself */
1010 if (!CmpFreeValue(Hive, ChildCell))
1011 {
1012 /* Failed to free the value, fail */
1014 goto Quickie;
1015 }
1016
1017 /* Set the last write time */
1018 KeQuerySystemTime(&Parent->LastWriteTime);
1019 Kcb->KcbLastWriteTime = Parent->LastWriteTime;
1020
1021 /* Sanity check */
1022 ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
1023 ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
1024 ASSERT(HvIsCellDirty(Hive, Cell));
1025
1026 /* Check if the value list is empty now */
1027 if (!Parent->ValueList.Count)
1028 {
1029 /* Then clear key node data */
1030 Parent->MaxValueNameLen = 0;
1031 Parent->MaxValueDataLen = 0;
1032 Kcb->KcbMaxValueNameLen = 0;
1033 Kcb->KcbMaxValueDataLen = 0;
1034 }
1035
1036 /* Cleanup the value cache */
1038
1039 /* Sanity checks */
1040 ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
1041 ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
1042
1043 /* Set the value cache */
1044 Kcb->ValueCache.Count = ChildList->Count;
1045 Kcb->ValueCache.ValueList = ChildList->List;
1046
1047 /* Notify registered callbacks */
1049
1050 /* Change default Status to success */
1052 }
1053
1054Quickie:
1055 /* Release the parent cell, if any */
1056 if (Parent) HvReleaseCell(Hive, Cell);
1057
1058 /* Check if we had a value */
1059 if (Value)
1060 {
1061 /* Release the child cell */
1062 ASSERT(ChildCell != HCELL_NIL);
1063 HvReleaseCell(Hive, ChildCell);
1064 }
1065
1066 /* Release locks */
1068 CmpReleaseKcbLock(Kcb);
1070 return Status;
1071}
unsigned char BOOLEAN
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:55
FORCEINLINE VOID CmpAcquireKcbLockExclusive(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:102
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:28
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:169
struct _CM_KEY_VALUE * PCM_KEY_VALUE
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431
BOOLEAN NTAPI CmpMarkValueDataDirty(IN PHHIVE Hive, IN PCM_KEY_VALUE Value)
Definition: cmvalue.c:19
BOOLEAN NTAPI CmpFreeValue(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: cmvalue.c:73
NTSTATUS NTAPI CmpRemoveValueFromList(IN PHHIVE Hive, IN ULONG Index, IN OUT PCHILD_LIST ChildList)
Definition: cmvalue.c:320
BOOLEAN CMAPI HvMarkCellDirty(PHHIVE RegistryHive, HCELL_INDEX CellOffset, BOOLEAN HoldingLock)
Definition: hivecell.c:109
BOOLEAN NTAPI CmpFindNameInList(IN PHHIVE Hive, IN PCHILD_LIST ChildList, IN PCUNICODE_STRING Name, OUT PULONG ChildIndex OPTIONAL, OUT PHCELL_INDEX CellIndex)
Definition: cmname.c:149
#define NULL
Definition: types.h:112
#define STATUS_KEY_DELETED
Definition: ntstatus.h:613
#define STATUS_NO_LOG_SPACE
Definition: ntstatus.h:614
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:481
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define REG_NOTIFY_CHANGE_LAST_SET
Definition: winreg.h:40
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426

Referenced by NtDeleteValueKey().

◆ CmEnumerateKey()

NTSTATUS NTAPI CmEnumerateKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Index,
IN KEY_INFORMATION_CLASS  KeyInformationClass,
IN PVOID  KeyInformation,
IN ULONG  Length,
IN PULONG  ResultLength 
)

Definition at line 1735 of file cmapi.c.

1741{
1743 PHHIVE Hive;
1745 HCELL_INDEX ChildCell;
1746 HV_TRACK_CELL_REF CellReferences = {0};
1747
1748 /* Acquire hive lock */
1750
1751 /* Lock the KCB shared */
1753
1754 /* Don't touch deleted keys */
1755 if (Kcb->Delete)
1756 {
1757 /* Undo everything */
1759 goto Quickie;
1760 }
1761
1762 /* Get the hive and parent */
1763 Hive = Kcb->KeyHive;
1764 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1765 ASSERT(Parent);
1766
1767 /* Get the child cell */
1768 ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index);
1769
1770 /* Release the parent cell */
1771 HvReleaseCell(Hive, Kcb->KeyCell);
1772
1773 /* Check if we found the child */
1774 if (ChildCell == HCELL_NIL)
1775 {
1776 /* We didn't, fail */
1778 goto Quickie;
1779 }
1780
1781 /* Now get the actual child node */
1782 Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
1783 ASSERT(Child);
1784
1785 /* Track references */
1786 if (!HvTrackCellRef(&CellReferences, Hive, ChildCell))
1787 {
1788 /* Can't allocate memory for tracking */
1790 goto Quickie;
1791 }
1792
1793 /* Data can be user-mode, use SEH */
1794 _SEH2_TRY
1795 {
1796 /* Query the data requested */
1797 Status = CmpQueryKeyData(Hive,
1798 Child,
1800 KeyInformation,
1801 Length,
1802 ResultLength);
1803 }
1805 {
1806 /* Fail with exception code */
1808 _SEH2_YIELD(goto Quickie);
1809 }
1810 _SEH2_END;
1811
1812Quickie:
1813 /* Release references */
1814 HvReleaseFreeCellRefArray(&CellReferences);
1815
1816 /* Release locks */
1817 CmpReleaseKcbLock(Kcb);
1819 return Status;
1820}
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:121
NTSTATUS NTAPI CmpQueryKeyData(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN KEY_INFORMATION_CLASS KeyInformationClass, IN OUT PVOID KeyInformation, IN ULONG Length, IN OUT PULONG ResultLength)
Definition: cmapi.c:376
HCELL_INDEX NTAPI CmpFindSubKeyByNumber(IN PHHIVE Hive, IN PCM_KEY_NODE Node, IN ULONG Number)
Definition: cmindex.c:600
BOOLEAN CMAPI HvTrackCellRef(IN OUT PHV_TRACK_CELL_REF CellRef, IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:554
VOID CMAPI HvReleaseFreeCellRefArray(IN OUT PHV_TRACK_CELL_REF CellRef)
Definition: hivecell.c:634
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
_In_ ULONG _In_ KEY_INFORMATION_CLASS KeyInformationClass
Definition: zwfuncs.h:167

Referenced by NtEnumerateKey().

◆ CmEnumerateValueKey()

NTSTATUS NTAPI CmEnumerateValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Index,
IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
IN PVOID  KeyValueInformation,
IN ULONG  Length,
IN PULONG  ResultLength 
)

Definition at line 1192 of file cmapi.c.

1198{
1200 PHHIVE Hive;
1202 HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL;
1204 BOOLEAN IndexIsCached, ValueIsCached = FALSE;
1205 PCELL_DATA CellData;
1206 PCM_CACHED_VALUE *CachedValue;
1208 PAGED_CODE();
1209
1210 /* Acquire hive lock */
1212
1213 /* Lock the KCB shared */
1215
1216 /* Don't touch deleted keys */
1217DoAgain:
1218 if (Kcb->Delete)
1219 {
1220 /* Undo everything */
1221 CmpReleaseKcbLock(Kcb);
1223 return STATUS_KEY_DELETED;
1224 }
1225
1226 /* Get the hive and parent */
1227 Hive = Kcb->KeyHive;
1228 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1229 ASSERT(Parent);
1230
1231 /* FIXME: Lack of cache? */
1232 if (Kcb->ValueCache.Count != Parent->ValueList.Count)
1233 {
1234 DPRINT1("HACK: Overriding value cache count\n");
1235 Kcb->ValueCache.Count = Parent->ValueList.Count;
1236 }
1237
1238 /* Make sure the index is valid */
1239 if (Index >= Kcb->ValueCache.Count)
1240 {
1241 /* Release the cell and fail */
1242 HvReleaseCell(Hive, Kcb->KeyCell);
1244 goto Quickie;
1245 }
1246
1247 /* We don't deal with this yet */
1248 if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
1249 {
1250 /* Shouldn't happen */
1251 ASSERT(FALSE);
1252 }
1253
1254 /* Find the value list */
1256 &CellData,
1257 &IndexIsCached,
1258 &CellToRelease);
1260 {
1261 /* Check if we need an exclusive lock */
1262 ASSERT(CellToRelease == HCELL_NIL);
1263 HvReleaseCell(Hive, Kcb->KeyCell);
1264
1265 /* Try with exclusive KCB lock */
1267 goto DoAgain;
1268 }
1269 else if (Result != SearchSuccess)
1270 {
1271 /* Sanity check */
1272 ASSERT(CellData == NULL);
1273
1274 /* Release the cell and fail */
1276 goto Quickie;
1277 }
1278
1279 /* Now get the key value */
1281 CellData,
1282 Index,
1283 &CachedValue,
1284 &ValueData,
1285 IndexIsCached,
1286 &ValueIsCached,
1287 &CellToRelease2);
1289 {
1290 /* Cleanup state */
1291 ASSERT(CellToRelease2 == HCELL_NIL);
1292 if (CellToRelease)
1293 {
1294 HvReleaseCell(Hive, CellToRelease);
1295 CellToRelease = HCELL_NIL;
1296 }
1297 HvReleaseCell(Hive, Kcb->KeyCell);
1298
1299 /* Try with exclusive KCB lock */
1301 goto DoAgain;
1302 }
1303 else if (Result != SearchSuccess)
1304 {
1305 /* Sanity check */
1306 ASSERT(ValueData == NULL);
1307
1308 /* Release the cells and fail */
1310 goto Quickie;
1311 }
1312
1313 /* User data, need SEH */
1314 _SEH2_TRY
1315 {
1316 /* Query the information requested */
1318 CachedValue,
1319 ValueData,
1320 ValueIsCached,
1322 KeyValueInformation,
1323 Length,
1325 &Status);
1327 {
1328 /* Cleanup state */
1329 if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2);
1330 HvReleaseCell(Hive, Kcb->KeyCell);
1331 if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
1332
1333 /* Try with exclusive KCB lock */
1335 _SEH2_YIELD(goto DoAgain);
1336 }
1337 }
1339 {
1340 /* Get exception code */
1342 }
1343 _SEH2_END;
1344
1345Quickie:
1346 /* If we have a cell to release, do so */
1347 if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1348
1349 /* Release the parent cell */
1350 HvReleaseCell(Hive, Kcb->KeyCell);
1351
1352 /* If we have a cell to release, do so */
1353 if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
1354
1355 /* Release locks */
1356 CmpReleaseKcbLock(Kcb);
1358 return Status;
1359}
#define PAGED_CODE()
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:189
VALUE_SEARCH_RETURN_TYPE NTAPI CmpQueryKeyValueData(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCM_KEY_VALUE ValueKey, IN BOOLEAN ValueIsCached, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength, OUT PNTSTATUS Status)
Definition: cmvalche.c:327
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, OUT PCELL_DATA *CellData, OUT BOOLEAN *IndexIsCached, OUT PHCELL_INDEX ValueListToRelease)
Definition: cmvalche.c:44
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueKeyFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCELL_DATA CellData, IN ULONG Index, OUT PCM_CACHED_VALUE **CachedValue, OUT PCM_KEY_VALUE *Value, IN BOOLEAN IndexIsCached, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:96
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:94

Referenced by NtEnumerateValueKey().

◆ CmFlushKey()

NTSTATUS NTAPI CmFlushKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN BOOLEAN  EclusiveLock 
)

Definition at line 1938 of file cmapi.c.

1940{
1941 PCMHIVE CmHive;
1943 PHHIVE Hive;
1944
1945 /* Ignore flushes until we're ready */
1946 if (CmpNoWrite) return STATUS_SUCCESS;
1947
1948 /* Get the hives */
1949 Hive = Kcb->KeyHive;
1950 CmHive = (PCMHIVE)Hive;
1951
1952 /* Check if this is the master hive */
1953 if (CmHive == CmiVolatileHive)
1954 {
1955 /* Flush all the hives instead */
1957 }
1958 else
1959 {
1960 /* Don't touch the hive */
1962
1963 ASSERT(CmHive->ViewLock);
1966
1967 /* Will the hive shrink? */
1968 if (HvHiveWillShrink(Hive))
1969 {
1970 /* I don't believe the current Hv does shrinking */
1971 ASSERT(FALSE);
1972 // CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive);
1973 }
1974 else
1975 {
1976 /* Now we can release views */
1977 ASSERT(CmHive->ViewLock);
1978 // CMP_ASSERT_VIEW_LOCK_OWNED(CmHive);
1980 (CmHive->HiveIsLoading == TRUE) ||
1981 (CmHive->ViewLockOwner == KeGetCurrentThread()) ||
1983 CmHive->ViewLockOwner = NULL;
1985 }
1986
1987 /* Flush only this hive */
1988 if (!HvSyncHive(Hive))
1989 {
1990 /* Fail */
1992 }
1993
1994 /* Release the flush lock */
1995 CmpUnlockHiveFlusher(CmHive);
1996 }
1997
1998 /* Return the status */
1999 return Status;
2000}
BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush)
Definition: cmapi.c:82
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
Definition: hivewrt.c:277
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
Definition: hivewrt.c:243
struct _CMHIVE * PCMHIVE
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:1894
BOOLEAN CmpSpecialBootCondition
Definition: cmsysini.c:28
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
BOOLEAN NTAPI CmpTestRegistryLockExclusive(VOID)
Definition: cmsysini.c:1886
BOOLEAN CmpNoWrite
Definition: cmsysini.c:29
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define KeGetCurrentThread
Definition: hal.h:55
#define STATUS_REGISTRY_IO_FAILED
Definition: ntstatus.h:569
BOOLEAN HiveIsLoading
Definition: cmlib.h:286
PKGUARDED_MUTEX ViewLock
Definition: cmlib.h:252
PKTHREAD ViewLockOwner
Definition: cmlib.h:253

Referenced by CmUnloadKey(), and NtFlushKey().

◆ CmGetSystemControlValues()

VOID NTAPI CmGetSystemControlValues ( IN PVOID  SystemHiveData,
IN PCM_SYSTEM_CONTROL_VECTOR  ControlVector 
)

Definition at line 104 of file cmcontrl.c.

106{
109 HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell;
114 BOOLEAN Auto, IsSmallKey;
116
117 /* LUDDDIIIICRROOOUUSSSS KI^H^H HACKKKK */
118 if (!SystemHiveData) return;
119
120 /* Initialize the Hive View List and the security cache */
124
125 /* Initialize the Hive */
130 SystemHiveData,
131 NULL,
132 NULL,
133 NULL,
134 NULL,
135 NULL,
136 NULL,
137 1,
138 NULL);
139 if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
140
141 /* Sanity check, flat hives don't have release routines */
143
144 /* Set the Root Cell */
145 RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
146
147 /* Find the current control set */
148 RtlInitUnicodeString(&KeyName, L"current");
149 BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto);
150 if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
151
152 /* Find the control subkey */
153 RtlInitUnicodeString(&KeyName, L"control");
156 if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
157
158 /* Loop each key */
159 while (ControlVector->KeyPath)
160 {
161 /* Assume failure */
162 Length = -1;
163
164 /* Get the cell for this key */
165 KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
166 if (KeyCell != HCELL_NIL)
167 {
168 /* Now get the cell for the value */
169 RtlInitUnicodeString(&KeyName, ControlVector->ValueName);
172 if (ValueCell != HCELL_NIL)
173 {
174 /* Check if there's any data */
175 if (!ControlVector->BufferLength)
176 {
177 /* No, the buffer will only be large enough for a ULONG */
178 DataSize = sizeof(ULONG);
179 }
180 else
181 {
182 /* Yes, save the data size */
183 DataSize = *ControlVector->BufferLength;
184 }
185
186 /* Get the actual data */
188
189 /* Check if this is a small key */
190 IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
191
192 /* If the length is bigger then our buffer, normalize it */
194
195 /* Make sure we have some data */
196 if (Length > 0)
197 {
198 /* Check if this was a small key */
199 if (IsSmallKey)
200 {
201 /* The buffer is directly safe to read */
202 Buffer = (PVOID)(&(ValueData->Data));
203 }
204 else
205 {
206 /* Use the longer path */
208 }
209
210 /* Sanity check if this is a small key */
211 ASSERT((IsSmallKey ?
213
214 /* Copy the data in the buffer */
215 RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
216 }
217
218 /* Check if we should return the data type */
219 if (ControlVector->Type)
220 {
221 /* Return the type that we read */
222 *ControlVector->Type = ValueData->Type;
223 }
224 }
225 }
226
227 /* Return the size that we read */
228 if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
229
230 /* Go to the next entry */
231 ControlVector++;
232 }
233
234 /* Check if the ID is in the registry */
236 {
237 /* Read it */
241 }
242 else
243 {
244 /* Use EN_US by default */
246 }
247
248 /* Check if the ID Is in the registry */
250 {
251 /* Read it */
254 }
255 else
256 {
257 /* Otherwise, use the default */
259 }
260
261 /* Set the defaults for the Thread UI */
264}
PHHIVE SystemHive
Definition: registry.c:32
Definition: bufpool.h:45
HCELL_INDEX NTAPI CmpFindControlSet(_In_ PHHIVE SystemHive, _In_ HCELL_INDEX RootCell, _In_ PCUNICODE_STRING SelectKeyName, _Out_ PBOOLEAN AutoSelect)
Finds the corresponding "HKLM\SYSTEM\ControlSetXXX" system control set registry key,...
Definition: cmboot.c:84
LANGID NTAPI CmpConvertLangId(IN LPWSTR Name, IN ULONG NameLength)
Definition: cmcontrl.c:22
HCELL_INDEX NTAPI CmpWalkPath(IN PHHIVE SystemHive, IN HCELL_INDEX ParentCell, IN LPWSTR Path)
Definition: cmcontrl.c:73
WCHAR CmInstallUILanguageId[12]
Definition: cmdata.c:26
ULONG CmDefaultLanguageIdLength
Definition: cmdata.c:23
ULONG CmDefaultLanguageIdType
Definition: cmdata.c:24
WCHAR CmDefaultLanguageId[12]
Definition: cmdata.c:22
ULONG CmInstallUILanguageIdLength
Definition: cmdata.c:27
CMHIVE CmControlHive
Definition: cmdata.c:34
ULONG CmInstallUILanguageIdType
Definition: cmdata.c:28
#define CM_KEY_VALUE_SMALL
Definition: cmdata.h:49
HCELL_INDEX NTAPI CmpFindSubKeyByName(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PCUNICODE_STRING SearchName)
Definition: cmindex.c:683
NTSTATUS CMAPI HvInitialize(PHHIVE RegistryHive, ULONG OperationType, ULONG HiveFlags, ULONG FileType, PVOID HiveData OPTIONAL, PALLOCATE_ROUTINE Allocate, PFREE_ROUTINE Free, PFILE_SET_SIZE_ROUTINE FileSetSize, PFILE_WRITE_ROUTINE FileWrite, PFILE_READ_ROUTINE FileRead, PFILE_FLUSH_ROUTINE FileFlush, ULONG Cluster OPTIONAL, PCUNICODE_STRING FileName OPTIONAL)
Definition: hiveinit.c:522
HCELL_INDEX NTAPI CmpFindValueByName(IN PHHIVE Hive, IN PCM_KEY_NODE KeyNode, IN PCUNICODE_STRING Name)
Definition: cmvalue.c:99
static BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length)
Definition: cmlib.h:319
VOID NTAPI CmpInitHiveViewList(IN PCMHIVE Hive)
Definition: cmmapvw.c:21
VOID NTAPI CmpInitSecurityCache(IN PCMHIVE Hive)
Definition: cmsecach.c:21
#define HINIT_FLAT
Definition: hivedata.h:17
#define HIVE_VOLATILE
Definition: hivedata.h:23
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
struct _HBASE_BLOCK * PHBASE_BLOCK
struct _HHIVE * PHHIVE
#define REG_SZ
Definition: layer.c:22
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
LANGID PsDefaultUILanguageId
Definition: locale.c:25
LANGID PsInstallUILanguageId
Definition: locale.c:21
LCID PsDefaultSystemLocaleId
Definition: locale.c:20
LCID PsDefaultThreadLocaleId
Definition: locale.c:24
#define L(x)
Definition: ntvdm.h:50
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:108
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13
PRELEASE_CELL_ROUTINE ReleaseCellRoutine
Definition: hivedata.h:292
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

Referenced by ExpInitializeExecutive().

◆ CmGetSystemDriverList()

PUNICODE_STRING *NTAPI CmGetSystemDriverList ( VOID  )

Definition at line 1727 of file cmsysini.c.

1728{
1729 LIST_ENTRY DriverList;
1732 PCM_KEY_BODY KeyBody;
1733 PHHIVE Hive;
1734 HCELL_INDEX RootCell, ControlCell;
1737 PLIST_ENTRY NextEntry;
1738 ULONG i;
1739 PUNICODE_STRING* ServicePath = NULL;
1740 BOOLEAN Success, AutoSelect;
1742 PAGED_CODE();
1743
1744 /* Initialize the driver list */
1745 InitializeListHead(&DriverList);
1746
1747 /* Open the system hive key */
1748 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
1750 &KeyName,
1752 NULL,
1753 NULL);
1755 if (!NT_SUCCESS(Status)) return NULL;
1756
1757 /* Reference the key object to get the root hive/cell to access directly */
1761 KernelMode,
1762 (PVOID*)&KeyBody,
1763 NULL);
1764 if (!NT_SUCCESS(Status))
1765 {
1766 /* Fail */
1768 return NULL;
1769 }
1770
1771 /* Do all this under the registry lock */
1773
1774 /* Get the hive and key cell */
1775 Hive = KeyBody->KeyControlBlock->KeyHive;
1776 RootCell = KeyBody->KeyControlBlock->KeyCell;
1777
1778 /* Open the current control set key */
1779 RtlInitUnicodeString(&KeyName, L"Current");
1780 ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
1781 if (ControlCell == HCELL_NIL) goto EndPath;
1782
1783 /* Find all system drivers */
1784 Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
1785 if (!Success) goto EndPath;
1786
1787 /* Sort by group/tag */
1788 if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
1789
1790 /* Remove circular dependencies (cycles) and sort */
1791 if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
1792
1793 /* Loop the list to count drivers */
1794 for (i = 0, NextEntry = DriverList.Flink;
1795 NextEntry != &DriverList;
1796 i++, NextEntry = NextEntry->Flink);
1797
1798 /* Allocate the array */
1799 ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING));
1800 if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1801
1802 /* Loop the driver list */
1803 for (i = 0, NextEntry = DriverList.Flink;
1804 NextEntry != &DriverList;
1805 i++, NextEntry = NextEntry->Flink)
1806 {
1807 /* Get the entry */
1809
1810 /* Allocate the path for the caller */
1811 ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING));
1812 if (!ServicePath[i])
1813 {
1814 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1815 }
1816
1817 /* Duplicate the registry path */
1819 &DriverEntry->RegistryPath,
1820 ServicePath[i]);
1821 if (!NT_SUCCESS(Status))
1822 {
1823 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1824 }
1825 }
1826
1827 /* Terminate the list */
1828 ServicePath[i] = NULL;
1829
1830EndPath:
1831 /* Free the driver list if we had one */
1832 if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
1833
1834 /* Unlock the registry */
1836
1837 /* Close the key handle and dereference the object, then return the path */
1838 ObDereferenceObject(KeyBody);
1840 return ServicePath;
1841}
BOOLEAN NTAPI CmpFindDrivers(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _In_ SERVICE_LOAD_TYPE LoadType, _In_opt_ PCWSTR BootFileSystem, _Inout_ PLIST_ENTRY DriverListHead)
Enumerates all drivers within the given control set and load type, present in the "Services" sub-key,...
Definition: cmboot.c:679
BOOLEAN NTAPI CmpResolveDriverDependencies(_Inout_ PLIST_ENTRY DriverListHead)
Removes potential circular dependencies (cycles) and sorts the driver list.
Definition: cmboot.c:1030
BOOLEAN NTAPI CmpSortDriverList(_In_ PHHIVE Hive, _In_ HCELL_INDEX ControlSet, _Inout_ PLIST_ENTRY DriverListHead)
Sorts the driver list, according to the drivers' group load ordering.
Definition: cmboot.c:902
VOID NTAPI CmpFreeDriverList(_In_ PHHIVE Hive, _Inout_ PLIST_ENTRY DriverListHead)
Empties the driver list and frees all allocated driver nodes in it.
Definition: cmboot.c:1224
VOID NTAPI CmpLockRegistryExclusive(VOID)
Definition: cmsysini.c:1845
POBJECT_TYPE CmpKeyObjectType
Definition: cmsysini.c:16
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
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 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE
Definition: green.h:15
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlDuplicateUnicodeString(int, const UNICODE_STRING *, UNICODE_STRING *)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
Definition: arc.h:199
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:222
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
static int Link(const char **args)
Definition: vfdcmd.c:2414
BOOL WINAPI EndPath(_In_ HDC)
@ SystemLoad
Definition: cmtypes.h:997
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IopInitializeSystemDrivers().

◆ CmiCallRegisteredCallbacks()

NTSTATUS CmiCallRegisteredCallbacks ( IN REG_NOTIFY_CLASS  Argument1,
IN PVOID  Argument2 
)

Definition at line 59 of file cmhook.c.

61{
62 PLIST_ENTRY CurrentEntry;
64 PREGISTRY_CALLBACK CurrentCallback;
65 PAGED_CODE();
66
68
69 for (CurrentEntry = CmiCallbackHead.Flink;
70 CurrentEntry != &CmiCallbackHead;
71 CurrentEntry = CurrentEntry->Flink)
72 {
73 CurrentCallback = CONTAINING_RECORD(CurrentEntry, REGISTRY_CALLBACK, ListEntry);
74 if (!CurrentCallback->PendingDelete &&
75 ExAcquireRundownProtection(&CurrentCallback->RundownRef))
76 {
77 /* don't hold locks during the callbacks! */
79
80 Status = CurrentCallback->Function(CurrentCallback->Context,
82 Argument2);
83
85
86 /* don't release the rundown protection before holding the callback lock
87 so the pointer to the next callback isn't cleared in case this callback
88 get's deleted */
89 ExReleaseRundownProtection(&CurrentCallback->RundownRef);
90 if(!NT_SUCCESS(Status))
91 {
92 /* one callback returned failure, don't call any more callbacks */
93 break;
94 }
95 }
96 }
97
99
100 return Status;
101}
_In_ PVOID Argument2
Definition: classpnp.h:721
LIST_ENTRY CmiCallbackHead
Definition: cmhook.c:20
FAST_MUTEX CmiCallbackLock
Definition: cmhook.c:21
#define ExReleaseRundownProtection
Definition: ex.h:135
#define ExAcquireRundownProtection
Definition: ex.h:134
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
EX_RUNDOWN_REF RundownRef
Definition: cmhook.c:26
PEX_CALLBACK_FUNCTION Function
Definition: cmhook.c:27
BOOLEAN PendingDelete
Definition: cmhook.c:30
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696

Referenced by CmpDeleteKeyObject(), NtDeleteKey(), NtDeleteValueKey(), NtEnumerateKey(), NtEnumerateValueKey(), NtQueryKey(), NtQueryValueKey(), and NtSetValueKey().

◆ CmInitSystem1()

BOOLEAN NTAPI CmInitSystem1 ( VOID  )

Definition at line 1511 of file cmsysini.c.

1512{
1517 PCMHIVE HardwareHive;
1519 PAGED_CODE();
1520
1521 /* Check if this is PE-boot */
1522 if (InitIsWinPEMode)
1523 {
1524 /* Set registry to PE mode */
1527 }
1528
1529 /* Initialize the hive list and lock */
1533
1534 /* Initialize registry lock */
1536
1537 /* Initialize the cache */
1539
1540 /* Initialize allocation and delayed dereferencing */
1544
1545 /* Initialize callbacks */
1547
1548 /* Initialize self healing */
1551
1552 /* Save the current process and lock the registry */
1554
1555 /* Create the key object types */
1557 if (!NT_SUCCESS(Status))
1558 {
1559 /* Bugcheck */
1560 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
1561 }
1562
1563 /* Build the master hive */
1568 NULL,
1569 NULL,
1570 NULL,
1571 NULL,
1572 NULL,
1573 0);
1574 if (!NT_SUCCESS(Status))
1575 {
1576 /* Bugcheck */
1577 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0);
1578 }
1579
1580 /* Create the \REGISTRY key node */
1581 if (!CmpCreateRegistryRoot())
1582 {
1583 /* Bugcheck */
1584 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
1585 }
1586
1587 /* Create the default security descriptor */
1589
1590 /* Create '\Registry\Machine' key */
1591 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
1593 &KeyName,
1595 NULL,
1600 0,
1601 NULL,
1602 0,
1603 NULL);
1604 if (!NT_SUCCESS(Status))
1605 {
1606 /* Bugcheck */
1607 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0);
1608 }
1609
1610 /* Close the handle */
1612
1613 /* Create '\Registry\User' key */
1614 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
1616 &KeyName,
1618 NULL,
1623 0,
1624 NULL,
1625 0,
1626 NULL);
1627 if (!NT_SUCCESS(Status))
1628 {
1629 /* Bugcheck */
1630 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0);
1631 }
1632
1633 /* Close the handle */
1635
1636 /* After this point, do not allow creating keys in the master hive */
1638
1639 /* Initialize the system hive */
1641 {
1642 /* Bugcheck */
1643 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
1644 }
1645
1646 /* Create the 'CurrentControlSet' link */
1648 if (!NT_SUCCESS(Status))
1649 {
1650 /* Bugcheck */
1651 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0);
1652 }
1653
1654 /* Create the hardware hive */
1655 Status = CmpInitializeHive(&HardwareHive,
1659 NULL,
1660 NULL,
1661 NULL,
1662 NULL,
1663 NULL,
1664 0);
1665 if (!NT_SUCCESS(Status))
1666 {
1667 /* Bugcheck */
1668 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
1669 }
1670
1671 /* Add the hive to the hive list */
1672 CmpMachineHiveList[0].CmHive = HardwareHive;
1673
1674 /* Attach it to the machine key */
1675 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE");
1677 NULL,
1678 HardwareHive,
1679 TRUE,
1681 if (!NT_SUCCESS(Status))
1682 {
1683 /* Bugcheck */
1684 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
1685 }
1686
1687 /* Add to HiveList key */
1688 CmpAddToHiveFileList(HardwareHive);
1689
1690 /* Free the security descriptor */
1692
1693 /* Fill out the Hardware key with the ARC Data from the Loader */
1695 if (!NT_SUCCESS(Status))
1696 {
1697 /* Bugcheck */
1698 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0);
1699 }
1700
1701 /* Initialize machine-dependent information into the registry */
1703 if (!NT_SUCCESS(Status))
1704 {
1705 /* Bugcheck */
1706 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 14, Status, 0);
1707 }
1708
1709 /* Initialize volatile registry settings */
1711 if (!NT_SUCCESS(Status))
1712 {
1713 /* Bugcheck */
1714 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0);
1715 }
1716
1717 /* Free the load options */
1719
1720 /* If we got here, all went well */
1721 return TRUE;
1722}
NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmhardwr.c:21
VOID NTAPI CmpInitCmPrivateAlloc(VOID)
Definition: cmalloc.c:29
VOID NTAPI CmpInitCmPrivateDelayAlloc(VOID)
Definition: cmalloc.c:44
NTSTATUS NTAPI CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmconfig.c:328
EX_PUSH_LOCK CmpHiveListHeadLock
Definition: cmdata.c:39
EX_PUSH_LOCK CmpLoadHiveLock
Definition: cmdata.c:39
HIVE_LIST_ENTRY CmpMachineHiveList[]
Definition: cmdata.c:41
BOOLEAN CmpMiniNTBoot
Definition: cmdata.c:60
BOOLEAN CmpShareSystemHives
Definition: cmdata.c:57
UNICODE_STRING CmpLoadOptions
Definition: cmdata.c:55
VOID NTAPI CmpInitDelayDerefKCBEngine(VOID)
Definition: cmdelay.c:268
VOID NTAPI CmpInitCallback(VOID)
Definition: cmhook.c:38
NTSTATUS NTAPI CmpAddToHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:130
VOID NTAPI CmpInitializeCache(VOID)
Definition: cmkcbncb.c:26
#define TAG_CM
Definition: cmlib.h:205
#define TAG_CMSD
Definition: cmlib.h:208
BOOLEAN NTAPI CmpCreateRegistryRoot(VOID)
Definition: cmsysini.c:1072
ERESOURCE CmpRegistryLock
Definition: cmsysini.c:19
NTSTATUS NTAPI CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE RegistryHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: cmsysini.c:798
PEPROCESS CmpSystemProcess
Definition: cmsysini.c:24
NTSTATUS NTAPI CmpCreateObjectTypes(VOID)
Definition: cmsysini.c:982
NTSTATUS NTAPI CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:524
BOOLEAN NTAPI CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:865
BOOLEAN CmpNoVolatileCreates
Definition: cmsysini.c:32
LIST_ENTRY CmpHiveListHead
Definition: cmsysini.c:18
LIST_ENTRY CmpSelfHealQueueListHead
Definition: cmsysini.c:21
KGUARDED_MUTEX CmpSelfHealQueueLock
Definition: cmsysini.c:20
NTSTATUS NTAPI CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:397
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExInitializePushLock
Definition: ex.h:1012
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define HINIT_CREATE
Definition: hivedata.h:13
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define KEY_WRITE
Definition: nt_native.h:1031
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *CmHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags)
Definition: cminit.c:19
PSECURITY_DESCRIPTOR NTAPI CmpHiveRootSecurityDescriptor(VOID)
Definition: cmse.c:21
BOOLEAN InitIsWinPEMode
Definition: init.c:72
PCMHIVE CmHive
Definition: cm.h:396
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by Phase1InitializationDiscard().

◆ CmLoadKey()

NTSTATUS NTAPI CmLoadKey ( IN POBJECT_ATTRIBUTES  TargetKey,
IN POBJECT_ATTRIBUTES  SourceFile,
IN ULONG  Flags,
IN PCM_KEY_BODY  KeyBody 
)

Definition at line 2004 of file cmapi.c.

2008{
2009 SECURITY_QUALITY_OF_SERVICE ServiceQos;
2010 SECURITY_CLIENT_CONTEXT ClientSecurityContext;
2013 PCMHIVE CmHive, LoadedHive;
2015 CM_PARSE_CONTEXT ParseContext;
2016
2017 /* Check if we have a trust key */
2018 if (KeyBody)
2019 {
2020 /* Fail */
2021 DPRINT("Trusted classes not yet supported\n");
2022 }
2023
2024 /* Build a service QoS for a security context */
2025 ServiceQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
2028 ServiceQos.EffectiveOnly = TRUE;
2030 &ServiceQos,
2031 FALSE,
2032 &ClientSecurityContext);
2033 if (!NT_SUCCESS(Status))
2034 {
2035 /* Fail */
2036 DPRINT1("Security context failed\n");
2037 return Status;
2038 }
2039
2040 /* Open the target key */
2041 RtlZeroMemory(&ParseContext, sizeof(ParseContext));
2042 ParseContext.CreateOperation = FALSE;
2043 Status = ObOpenObjectByName(TargetKey,
2045 KernelMode,
2046 NULL,
2047 KEY_READ,
2048 &ParseContext,
2049 &KeyHandle);
2051
2052 /* Open the hive */
2053 Status = CmpCmdHiveOpen(SourceFile,
2054 &ClientSecurityContext,
2055 &Allocate,
2056 &CmHive,
2057 0);
2058
2059 /* Get rid of the security context */
2060 SeDeleteClientSecurity(&ClientSecurityContext);
2061
2062 /* See if we failed */
2063 if (!NT_SUCCESS(Status))
2064 {
2065 /* See if the target already existed */
2066 if (KeyHandle)
2067 {
2068 /* Lock the registry */
2070
2071 /* Check if we are already loaded */
2072 if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive))
2073 {
2074 /* That's okay then */
2075 ASSERT(LoadedHive);
2077 }
2078
2079 /* Release the registry */
2081 }
2082
2083 /* Close the key handle if we had one */
2085 return Status;
2086 }
2087
2088 /* Lock the registry shared */
2090
2091 /* Lock loading */
2093
2094 /* Lock the hive to this thread */
2095 CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
2096 CmHive->CreatorOwner = KeGetCurrentThread();
2097
2098 /* Set flag */
2100
2101 /* Link the hive */
2102 Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
2103 TargetKey->RootDirectory,
2104 CmHive,
2105 Allocate,
2106 TargetKey->SecurityDescriptor);
2107 if (NT_SUCCESS(Status))
2108 {
2109 /* Add to HiveList key */
2110 CmpAddToHiveFileList(CmHive);
2111
2112 /* Sync the hive if necessary */
2113 if (Allocate)
2114 {
2115 /* Sync it under the flusher lock */
2117 HvSyncHive(&CmHive->Hive);
2118 CmpUnlockHiveFlusher(CmHive);
2119 }
2120
2121 /* Release the hive */
2122 CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING;
2123 CmHive->CreatorOwner = NULL;
2124 }
2125 else
2126 {
2127 DPRINT1("CmpLinkHiveToMaster failed, Status %lx\n", Status);
2128
2129 /* We're touching this hive, set the loading flag */
2130 CmHive->HiveIsLoading = TRUE;
2131
2132 /* Close associated file handles */
2133 CmpCloseHiveFiles(CmHive);
2134
2135 /* Cleanup its resources */
2136 CmpDestroyHive(CmHive);
2137 }
2138
2139 /* Allow loads */
2141
2142 /* Is this first profile load? */
2144 {
2145 /* User is now logged on, set quotas */
2148 }
2149
2150 /* Unlock the registry */
2152
2153 /* Close handle and return */
2155 return Status;
2156}
#define CmpKeyObjectType
Definition: ObTypes.c:127
BOOLEAN NTAPI CmpIsHiveAlreadyLoaded(IN HANDLE KeyHandle, IN POBJECT_ATTRIBUTES SourceFile, OUT PCMHIVE *CmHive)
Definition: cmapi.c:21
NTSTATUS NTAPI CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes, IN PSECURITY_CLIENT_CONTEXT ImpersonationContext, IN OUT PBOOLEAN Allocate, OUT PCMHIVE *NewHive, IN ULONG CheckFlags)
Definition: cmlazy.c:272
VOID NTAPI CmpSetGlobalQuotaAllowed(VOID)
Definition: cmquota.c:22
BOOLEAN CmpProfileLoaded
Definition: cmsysini.c:31
BOOLEAN CmpWasSetupBoot
Definition: cmsysini.c:30
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1295
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1035
#define HIVE_IS_UNLOADING
Definition: hivedata.h:28
#define HIVE_NOLAZYFLUSH
Definition: hivedata.h:24
@ SecurityImpersonation
Definition: lsa.idl:57
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
#define SeDeleteClientSecurity(C)
Definition: imports.h:320
NTKERNELAPI NTSTATUS NTAPI SeCreateClientSecurity(IN PETHREAD Thread, IN PSECURITY_QUALITY_OF_SERVICE QualityOfService, IN BOOLEAN RemoteClient, OUT PSECURITY_CLIENT_CONTEXT ClientContext)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define REG_NO_LAZY_FLUSH
Definition: nt_native.h:1093
VOID NTAPI CmpCloseHiveFiles(IN PCMHIVE Hive)
Definition: cminit.c:637
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive)
Definition: cminit.c:235
NTSTATUS NTAPI ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN PACCESS_STATE PassedAccessState, IN ACCESS_MASK DesiredAccess, IN OUT PVOID ParseContext, OUT PHANDLE Handle)
Definition: obhandle.c:2532
#define DPRINT
Definition: sndvol32.h:71
HHIVE Hive
Definition: cmlib.h:246
PKTHREAD CreatorOwner
Definition: cmlib.h:287
BOOLEAN CreateOperation
Definition: cm.h:417
ULONG HiveFlags
Definition: hivedata.h:321
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
_In_opt_ PALLOCATE_FUNCTION Allocate
Definition: exfuncs.h:814
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103

Referenced by NtLoadKeyEx().

◆ CmpAcquireTwoKcbLocksExclusiveByKey()

VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey ( IN ULONG  ConvKey1,
IN ULONG  ConvKey2 
)

Definition at line 1967 of file cmsysini.c.

1969{
1970 ULONG Index1, Index2;
1971
1972 /* Sanity check */
1974
1975 /* Get hash indexes */
1976 Index1 = GET_HASH_INDEX(ConvKey1);
1977 Index2 = GET_HASH_INDEX(ConvKey2);
1978
1979 /* See which one is highest */
1980 if (Index1 < Index2)
1981 {
1982 /* Grab them in the proper order */
1985 }
1986 else
1987 {
1988 /* Grab the second one first, then the first */
1990 if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
1991 }
1992}
FORCEINLINE VOID CmpAcquireKcbLockExclusiveByKey(IN ULONG ConvKey)
Definition: cm_x.h:112
#define GET_HASH_INDEX(ConvKey)
Definition: cm_x.h:18
#define CMP_ASSERT_REGISTRY_LOCK()
Definition: cm_x.h:46

Referenced by CmDeleteKey(), CmpCreateKeyControlBlock(), and NtUnloadKey2().

◆ CmpAddToDelayedClose()

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

Definition at line 350 of file cmdelay.c.

352{
353 ULONG i;
354 ULONG OldRefCount, NewRefCount;
356 PAGED_CODE();
357
358 /* Sanity check */
360
361 /* Make sure it's valid */
362 if (Kcb->DelayedCloseIndex != CmpDelayedCloseSize) ASSERT(FALSE);
363
364 /* Sanity checks */
365 ASSERT(Kcb->RefCount == 0);
366 ASSERT(IsListEmpty(&Kcb->KeyBodyListHead) == TRUE);
367 for (i = 0; i < 4; i++) ASSERT(Kcb->KeyBodyArray[i] == NULL);
368
369 /* Allocate a delay item */
371 if (!Entry)
372 {
373 /* Cleanup immediately */
374 CmpCleanUpKcbCacheWithLock(Kcb, LockHeldExclusively);
375 return;
376 }
377
378 /* Sanity check */
379 if (Kcb->InDelayClose) ASSERT(FALSE);
380
381 /* Get the previous reference count */
382 OldRefCount = *(PLONG)&Kcb->InDelayClose;
383 ASSERT(OldRefCount == 0);
384
385 /* Write the new one */
386 NewRefCount = 1;
387 if (InterlockedCompareExchange((PLONG)&Kcb->InDelayClose,
388 NewRefCount,
389 OldRefCount) != OldRefCount)
390 {
391 /* Sanity check */
392 ASSERT(FALSE);
393 }
394
395 /* Reset the delayed close index */
396 Kcb->DelayedCloseIndex = 0;
397
398 /* Set up the close entry */
399 Kcb->DelayCloseEntry = Entry;
400 Entry->KeyControlBlock = Kcb;
401
402 /* Increase the number of elements */
404
405 /* Acquire the delayed close table lock */
407
408 /* Insert the entry into the list */
409 InsertHeadList(&CmpDelayedLRUListHead, &Entry->DelayedLRUList);
410
411 /* Check if we need to enable anything */
414 {
415 /* Yes, we have too many elements to close, and no work item */
417 }
418
419 /* Release the table lock */
421}
#define InterlockedIncrement
Definition: armddk.h:53
#define CMP_ASSERT_KCB_LOCK(k)
Definition: cm_x.h:245
PVOID NTAPI CmpAllocateDelayItem(VOID)
Definition: cmalloc.c:196
ULONG CmpDelayedCloseSize
Definition: cmdelay.c:19
VOID NTAPI CmpArmDelayedCloseTimer(VOID)
Definition: cmdelay.c:335
LIST_ENTRY CmpDelayedLRUListHead
Definition: cmdelay.c:24
KGUARDED_MUTEX CmpDelayedCloseTableLock
Definition: cmdelay.c:21
ULONG CmpDelayedCloseElements
Definition: cmdelay.c:20
BOOLEAN CmpDelayCloseWorkItemActive
Definition: cmdelay.c:22
VOID NTAPI CmpCleanUpKcbCacheWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:476
#define InsertHeadList(ListHead, Entry)
#define InterlockedCompareExchange
Definition: interlocked.h:104
base of all file and directory entries
Definition: entries.h:83
Definition: cm.h:351
int32_t * PLONG
Definition: typedefs.h:58

Referenced by CmpDereferenceKeyControlBlockWithLock().

◆ CmpAddToHiveFileList()

NTSTATUS NTAPI CmpAddToHiveFileList ( IN PCMHIVE  Hive)

Definition at line 130 of file cmhvlist.c.

131{
135 UNICODE_STRING HivePath;
138 OBJECT_NAME_INFORMATION DummyNameInfo;
139 POBJECT_NAME_INFORMATION FileNameInfo;
140
141 HivePath.Buffer = NULL;
142 FileNameInfo = NULL;
143
144 /* Create or open the hive list key */
148 NULL,
149 NULL);
150 Status = ZwCreateKey(&KeyHandle,
153 0,
154 NULL,
156 NULL);
157 if (!NT_SUCCESS(Status))
158 {
159 /* Fail */
160 DPRINT1("CmpAddToHiveFileList: Creation or opening of the hive list failed, status = 0x%08lx\n", Status);
161 return Status;
162 }
163
164 /* Retrieve the name of the hive */
165 if (!CmpGetHiveName(Hive, &HivePath))
166 {
167 /* Fail */
168 DPRINT1("CmpAddToHiveFileList: Unable to retrieve the hive name\n");
170 goto Quickie;
171 }
172
173 /* Get the name of the corresponding file */
174 if (!(Hive->Hive.HiveFlags & HIVE_VOLATILE))
175 {
176 /* Determine the right buffer size and allocate */
177 Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY],
179 &DummyNameInfo,
180 sizeof(DummyNameInfo),
181 &Length);
183 {
184 DPRINT1("CmpAddToHiveFileList: Hive file name size query failed, status = 0x%08lx\n", Status);
185 goto Quickie;
186 }
187
188 FileNameInfo = ExAllocatePoolWithTag(PagedPool,
189 Length + sizeof(UNICODE_NULL),
190 TAG_CM);
191 if (FileNameInfo == NULL)
192 {
194 goto Quickie;
195 }
196
197 /* Try to get the value */
198 Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY],
200 FileNameInfo,
201 Length,
202 &Length);
203 if (NT_SUCCESS(Status))
204 {
205 /* Null-terminate and add the length of the terminator */
207 FilePath = FileNameInfo->Name.Buffer;
208 FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
209 Length += sizeof(UNICODE_NULL);
210 }
211 else
212 {
213 /* Fail */
214 DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = 0x%08lx\n", Status);
215 goto Quickie;
216 }
217 }
218 else
219 {
220 /* No name */
221 FilePath = L"";
222 Length = sizeof(UNICODE_NULL);
223 }
224
225 /* Set the entry in the hive list */
226 Status = ZwSetValueKey(KeyHandle,
227 &HivePath,
228 0,
229 REG_SZ,
230 FilePath,
231 Length);
232 if (!NT_SUCCESS(Status))
233 {
234 /* Fail */
235 DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed, status = 0x%08lx\n", Status);
236 }
237
238Quickie:
239 /* Cleanup and return status */
240 if (HivePath.Buffer)
241 {
243 }
244 if (FileNameInfo)
245 {
246 ExFreePoolWithTag(FileNameInfo, TAG_CM);
247 }
249 return Status;
250}
@ ObjectNameInformation
Definition: DriverTester.h:55
PCWSTR FilePath
BOOLEAN NTAPI CmpGetHiveName(IN PCMHIVE Hive, OUT PUNICODE_STRING HiveName)
Definition: cmhvlist.c:24
UNICODE_STRING HiveListValueName
Definition: cmhvlist.c:17
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define UNICODE_NULL
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
UNICODE_STRING Name
Definition: nt_native.h:1270
uint16_t * PWCHAR
Definition: typedefs.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by CmInitSystem1(), CmLoadKey(), and CmpInitializeHiveList().

◆ CmpAllocate()

PVOID NTAPI CmpAllocate ( IN SIZE_T  Size,
IN BOOLEAN  Paged,
IN ULONG  Tag 
)

Definition at line 46 of file registry.c.

50{
52 return FrLdrHeapAlloc(Size, Tag);
53}
FORCEINLINE PVOID FrLdrHeapAlloc(SIZE_T MemorySize, ULONG Tag)
Definition: mm.h:174
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ CmpAllocateDelayItem()

PVOID NTAPI CmpAllocateDelayItem ( VOID  )

Definition at line 196 of file cmalloc.c.

197{
199 PCM_ALLOC_PAGE AllocPage;
200 ULONG i;
201 PLIST_ENTRY NextEntry;
202 PAGED_CODE();
203
204 /* Lock the allocation buckets */
206
207 /* Look for an item on the free list */
208SearchList:
210 {
211 /* Get the current entry in the list */
213
214 /* Grab the item */
215 Entry = CONTAINING_RECORD(NextEntry, CM_DELAY_ALLOC, ListEntry);
216
217 /* Clear the list */
218 Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL;
219
220 /* Grab the alloc page */
222
223 /* Decrease free entries */
224 ASSERT(AllocPage->FreeCount != 0);
225 AllocPage->FreeCount--;
226
227 /* Release the lock */
229 return Entry;
230 }
231
232 /* Allocate an allocation page */
233 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_CM);
234 if (AllocPage)
235 {
236 /* Set default entries */
237 AllocPage->FreeCount = CM_DELAYS_PER_PAGE;
238
239 /* Loop each entry */
240 for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
241 {
242 /* Get this entry and link it */
243 Entry = (PVOID)((ULONG_PTR)AllocPage +
244 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
245 i * sizeof(CM_DELAY_ALLOC));
247 &Entry->ListEntry);
248
249 /* Clear the KCB pointer */
250 Entry->Kcb = NULL;
251 }
252 }
253 else
254 {
255 /* Release the lock */
257 return NULL;
258 }
259
260 /* Do the search again */
261 goto SearchList;
262}
PVOID NTAPI CmpAllocate(_In_ SIZE_T Size, _In_ BOOLEAN Paged, _In_ ULONG Tag)
Definition: bootreg.c:90
struct _CM_DELAY_ALLOC CM_DELAY_ALLOC
#define CM_DELAYS_PER_PAGE
Definition: cm.h:119
#define CmpGetAllocPageFromDelayAlloc(a)
Definition: cm_x.h:260
LIST_ENTRY CmpFreeDelayItemsListHead
Definition: cmalloc.c:22
KGUARDED_MUTEX CmpDelayAllocBucketLock
Definition: cmalloc.c:18
#define InsertTailList(ListHead, Entry)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
ULONG FreeCount
Definition: cm.h:333
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by CmpAddToDelayedClose(), and CmpDelayDerefKeyControlBlock().

◆ CmpAllocateKeyControlBlock()

PCM_KEY_CONTROL_BLOCK NTAPI CmpAllocateKeyControlBlock ( VOID  )

Definition at line 111 of file cmalloc.c.

112{
113 PLIST_ENTRY NextEntry;
114 PCM_KEY_CONTROL_BLOCK CurrentKcb;
115 PCM_ALLOC_PAGE AllocPage;
116 ULONG i;
117 PAGED_CODE();
118
119 /* Check if private allocations are initialized */
120 if (CmpAllocInited)
121 {
122 /* They are, acquire the bucket lock */
124
125 /* See if there's something on the free KCB list */
126SearchKcbList:
128 {
129 /* Remove the entry */
131
132 /* Get the KCB */
133 CurrentKcb = CONTAINING_RECORD(NextEntry,
135 FreeListEntry);
136
137 /* Get the allocation page */
138 AllocPage = CmpGetAllocPageFromKcb(CurrentKcb);
139
140 /* Decrease the free count */
141 ASSERT(AllocPage->FreeCount != 0);
142 AllocPage->FreeCount--;
143
144 /* Make sure this KCB is privately allocated */
145 ASSERT(CurrentKcb->PrivateAlloc == 1);
146
147 /* Release the allocation lock */
149
150 /* Return the KCB */
151 return CurrentKcb;
152 }
153
154 /* Allocate an allocation page */
155 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_KCB);
156 if (AllocPage)
157 {
158 /* Set default entries */
159 AllocPage->FreeCount = CM_KCBS_PER_PAGE;
160
161 /* Loop each entry */
162 for (i = 0; i < CM_KCBS_PER_PAGE; i++)
163 {
164 /* Get this entry */
165 CurrentKcb = (PVOID)((ULONG_PTR)AllocPage +
166 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
167 i * sizeof(CM_KEY_CONTROL_BLOCK));
168
169 /* Set it up */
170 CurrentKcb->PrivateAlloc = TRUE;
171 CurrentKcb->DelayCloseEntry = NULL;
173 &CurrentKcb->FreeListEntry);
174 }
175
176 /* Now go back and search the list */
177 goto SearchKcbList;
178 }
179 }
180
181 /* Allocate a KCB only */
182 CurrentKcb = CmpAllocate(sizeof(CM_KEY_CONTROL_BLOCK), TRUE, TAG_KCB);
183 if (CurrentKcb)
184 {
185 /* Set it up */
186 CurrentKcb->PrivateAlloc = 0;
187 CurrentKcb->DelayCloseEntry = NULL;
188 }
189
190 /* Return it */
191 return CurrentKcb;
192}
#define CM_KCBS_PER_PAGE
Definition: cm.h:117
struct _CM_KEY_CONTROL_BLOCK CM_KEY_CONTROL_BLOCK
#define CmpGetAllocPageFromKcb(k)
Definition: cm_x.h:254
LIST_ENTRY CmpFreeKCBListHead
Definition: cmalloc.c:20
BOOLEAN CmpAllocInited
Definition: cmalloc.c:17
KGUARDED_MUTEX CmpAllocBucketLock
Definition: cmalloc.c:18
#define TAG_KCB
Definition: cmlib.h:206
ULONG PrivateAlloc
Definition: cm.h:258
LIST_ENTRY FreeListEntry
Definition: cm.h:287
PVOID DelayCloseEntry
Definition: cm.h:290

Referenced by CmpCreateKeyControlBlock().

◆ CmpArmDelayedCloseTimer()

VOID NTAPI CmpArmDelayedCloseTimer ( VOID  )

Definition at line 335 of file cmdelay.c.

336{
338 PAGED_CODE();
339
340 /* Set the worker active */
342
343 /* Setup the interval */
344 Timeout.QuadPart = CmpDelayCloseIntervalInSeconds * -10000000;
346}
KDPC CmpDelayCloseDpc
Definition: cmdelay.c:26
ULONG CmpDelayCloseIntervalInSeconds
Definition: cmdelay.c:25
KTIMER CmpDelayCloseTimer
Definition: cmdelay.c:27
static ULONG Timeout
Definition: ping.c:61
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281

Referenced by _Function_class_(), and CmpAddToDelayedClose().

◆ 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 */
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}
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
#define CM_KCB_SUBKEY_HINT
Definition: cm.h:54
#define CM_KCB_INVALID_SIGNATURE
Definition: cm.h:47
VOID NTAPI CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmalloc.c:53
VOID NTAPI CmpDelayDerefKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:286
VOID NTAPI CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN LockHeldExclusively)
Definition: cmkcbncb.c:606
VOID NTAPI CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb)
Definition: cmkcbncb.c:317

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 */
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 CM_KCB_NO_DELAY_CLOSE
Definition: cm.h:57
#define CMP_GET_CACHED_DATA(c)
Definition: cm_x.h:36
#define CMP_GET_CACHED_CELL(c)
Definition: cm_x.h:34
uint32_t * PULONG_PTR
Definition: typedefs.h:65

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 */
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 */
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 CM_KCB_SUBKEY_ONE
Definition: cm.h:53
#define CM_KCB_INVALID_CACHED_INFO
Definition: cm.h:58
#define CM_KCB_NO_SUBKEY
Definition: cm.h:52
ULONG SubKeyCounts[HTYPE_COUNT]
Definition: cmdata.h:97

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

◆ CmpCloseHiveFiles()

VOID NTAPI CmpCloseHiveFiles ( IN PCMHIVE  Hive)

Definition at line 637 of file cminit.c.

638{
639 ULONG i;
640
641 for (i = 0; i < HFILE_TYPE_MAX; i++)
642 {
643 if (Hive->FileHandles[i] != NULL)
644 {
645 ZwClose(Hive->FileHandles[i]);
646 Hive->FileHandles[i] = NULL;
647 }
648 }
649}
#define HFILE_TYPE_MAX
Definition: hivedata.h:36

Referenced by CmLoadKey(), CmShutdownSystem(), and CmUnloadKey().

◆ CmpCloseKeyObject()

VOID NTAPI CmpCloseKeyObject ( IN PEPROCESS Process  OPTIONAL,
IN PVOID  Object,
IN ACCESS_MASK  GrantedAccess,
IN ULONG  ProcessHandleCount,
IN ULONG  SystemHandleCount 
)

Definition at line 159 of file cmsysini.c.

164{
166 PAGED_CODE();
167
168 /* Don't do anything if we're not the last handle */
169 if (SystemHandleCount > 1) return;
170
171 /* Make sure we're a valid key body */
172 if (KeyBody->Type == CM_KEY_BODY_TYPE)
173 {
174 /* Don't do anything if we don't have a notify block */
175 if (!KeyBody->NotifyBlock) return;
176
177 /* This shouldn't happen yet */
178 ASSERT(FALSE);
179 }
180}
struct _CM_KEY_BODY * PCM_KEY_BODY
#define CM_KEY_BODY_TYPE
Definition: cm.h:64
ULONG Type
Definition: cm.h:221
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:223
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object

Referenced by CmpCreateObjectTypes().

◆ CmpCmdHiveOpen()

NTSTATUS NTAPI CmpCmdHiveOpen ( IN POBJECT_ATTRIBUTES  FileAttributes,
IN PSECURITY_CLIENT_CONTEXT  ImpersonationContext,
IN OUT PBOOLEAN  Allocate,
OUT PCMHIVE NewHive,
IN ULONG  CheckFlags 
)

Definition at line 272 of file cmlazy.c.

277{
282 OBJECT_NAME_INFORMATION DummyNameInfo;
283 POBJECT_NAME_INFORMATION FileNameInfo;
284
285 PAGED_CODE();
286
287 if (FileAttributes->RootDirectory)
288 {
289 /*
290 * Validity check: The ObjectName is relative to RootDirectory,
291 * therefore it must not start with a path separator.
292 */
293 if (FileAttributes->ObjectName && FileAttributes->ObjectName->Buffer &&
294 FileAttributes->ObjectName->Length >= sizeof(WCHAR) &&
295 *FileAttributes->ObjectName->Buffer == OBJ_NAME_PATH_SEPARATOR)
296 {
298 }
299
300 /* Determine the right buffer size and allocate */
301 Status = ZwQueryObject(FileAttributes->RootDirectory,
303 &DummyNameInfo,
304 sizeof(DummyNameInfo),
305 &Length);
307 {
308 DPRINT1("CmpCmdHiveOpen(): Root directory handle object name size query failed, Status = 0x%08lx\n", Status);
309 return Status;
310 }
311
312 FileNameInfo = ExAllocatePoolWithTag(PagedPool,
313 Length + sizeof(UNICODE_NULL),
314 TAG_CM);
315 if (FileNameInfo == NULL)
316 {
317 DPRINT1("CmpCmdHiveOpen(): Unable to allocate memory\n");
319 }
320
321 /* Try to get the value */
322 Status = ZwQueryObject(FileAttributes->RootDirectory,
324 FileNameInfo,
325 Length,
326 &Length);
327 if (!NT_SUCCESS(Status))
328 {
329 /* Fail */
330 DPRINT1("CmpCmdHiveOpen(): Root directory handle object name query failed, Status = 0x%08lx\n", Status);
331 ExFreePoolWithTag(FileNameInfo, TAG_CM);
332 return Status;
333 }
334
335 /* Null-terminate and add the length of the terminator */
337 FilePath = FileNameInfo->Name.Buffer;
338 FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
339 Length += sizeof(UNICODE_NULL);
340
341 /* Compute the size of the full path; Length already counts the terminating NULL */
342 Length = Length + sizeof(WCHAR) + FileAttributes->ObjectName->Length;
344 {
345 /* Name size too long, bail out */
346 ExFreePoolWithTag(FileNameInfo, TAG_CM);
348 }
349
350 /* Build the full path */
351 RtlInitEmptyUnicodeString(&FileName, NULL, 0);
353 if (!FileName.Buffer)
354 {
355 /* Fail */
356 DPRINT1("CmpCmdHiveOpen(): Unable to allocate memory\n");
357 ExFreePoolWithTag(FileNameInfo, TAG_CM);
359 }
360 FileName.MaximumLength = Length;
361 RtlCopyUnicodeString(&FileName, &FileNameInfo->Name);
362 ExFreePoolWithTag(FileNameInfo, TAG_CM);
363
364 /*
365 * Append a path terminator if needed (we have already accounted
366 * for a possible extra one when allocating the buffer).
367 */
368 if (/* FileAttributes->ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR && */ // We excluded ObjectName starting with a path separator above.
369 FileName.Length > 0 && FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR)
370 {
371 /* ObjectName does not start with '\' and PathBuffer does not end with '\' */
372 FileName.Buffer[FileName.Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
373 FileName.Length += sizeof(WCHAR);
374 FileName.Buffer[FileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
375 }
376
377 /* Append the object name */
379 if (!NT_SUCCESS(Status))
380 {
381 /* Fail */
382 DPRINT1("CmpCmdHiveOpen(): RtlAppendUnicodeStringToString() failed, Status = 0x%08lx\n", Status);
384 return Status;
385 }
386 }
387 else
388 {
389 FileName = *FileAttributes->ObjectName;
390 }
391
392 /* Open the file in the current security context */
394 0,
395 NewHive,
396 Allocate,
397 CheckFlags);
398 if (((Status == STATUS_ACCESS_DENIED) ||
404 (ImpersonationContext))
405 {
406 /* We failed due to an account/security error, impersonate SYSTEM */
407 Status = SeImpersonateClientEx(ImpersonationContext, NULL);
408 if (NT_SUCCESS(Status))
409 {
410 /* Now try again */
412 0,
413 NewHive,
414 Allocate,
415 CheckFlags);
416
417 /* Restore impersonation token */
419 }
420 }
421
422 if (FileAttributes->RootDirectory)
423 {
425 }
426
427 /* Return status of open attempt */
428 return Status;
429}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
NTSTATUS NTAPI CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName, IN ULONG HiveFlags, OUT PCMHIVE *Hive, IN OUT PBOOLEAN New, IN ULONG CheckFlags)
Definition: cmsysini.c:286
struct _FileName FileName
Definition: fatprocs.h:896
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
if(dx< 0)
Definition: linetemp.h:194
NTKERNELAPI VOID NTAPI PsRevertToSelf(VOID)
Definition: security.c:556
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSTATUS NTAPI SeImpersonateClientEx(_In_ PSECURITY_CLIENT_CONTEXT ClientContext, _In_opt_ PETHREAD ServerThread)
Extended function that impersonates a client.
Definition: client.c:276
#define STATUS_WRONG_PASSWORD
Definition: ntstatus.h:342
#define STATUS_ACCOUNT_DISABLED
Definition: ntstatus.h:350
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_NO_SUCH_USER
Definition: ntstatus.h:336
#define STATUS_ACCOUNT_EXPIRED
Definition: ntstatus.h:636
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define STATUS_ACCOUNT_RESTRICTION
Definition: ntstatus.h:346
#define MAXUSHORT
Definition: typedefs.h:83
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by CmLoadKey().

◆ CmpCmdInit()

VOID NTAPI CmpCmdInit ( IN BOOLEAN  SetupBoot)

Definition at line 234 of file cmlazy.c.

235{
237 PAGED_CODE();
238
239 /* Setup the lazy DPC */
240 KeInitializeDpc(&CmpLazyFlushDpc, CmpLazyFlushDpcRoutine, NULL);
241
242 /* Setup the lazy timer */
244
245 /* Setup the lazy worker */
246 ExInitializeWorkItem(&CmpLazyWorkItem, CmpLazyFlushWorker, NULL);
247
248 /* Setup the forced-lazy DPC and timer */
250 CmpEnableLazyFlushDpcRoutine,
251 NULL);
253
254 /* Enable lazy flushing after 10 minutes */
255 DueTime.QuadPart = Int32x32To64(600, -10 * 1000 * 1000);
257
258 /* Setup flush variables */
260 CmpWasSetupBoot = SetupBoot;
261
262 /* Testing: Force Lazy Flushing */
264
265 /* Setup the hive list if this is not a Setup boot */
266 if (!SetupBoot)
268}
KDPC CmpEnableLazyFlushDpc
Definition: cmlazy.c:21
KTIMER CmpEnableLazyFlushTimer
Definition: cmlazy.c:20
KDPC CmpLazyFlushDpc
Definition: cmlazy.c:18
WORK_QUEUE_ITEM CmpLazyWorkItem
Definition: cmlazy.c:19
BOOLEAN CmpHoldLazyFlush
Definition: cmlazy.c:24
KTIMER CmpLazyFlushTimer
Definition: cmlazy.c:17
VOID NTAPI CmpInitializeHiveList(VOID)
Definition: cmsysini.c:1358
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define Int32x32To64(a, b)
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
_In_ WDFTIMER _In_ LONGLONG DueTime
Definition: wdftimer.h:190
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265

Referenced by NtInitializeRegistry().

◆ CmpCompareNewValueDataAgainstKCBCache()

VALUE_SEARCH_RETURN_TYPE NTAPI CmpCompareNewValueDataAgainstKCBCache ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN PUNICODE_STRING  ValueName,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize 
)

Definition at line 700 of file cmvalche.c.

705{
706 VALUE_SEARCH_RETURN_TYPE SearchResult;
707 PCM_KEY_NODE KeyNode;
708 PCM_CACHED_VALUE *CachedValue;
709 ULONG Index;
711 BOOLEAN ValueCached, BufferAllocated = FALSE;
713 HCELL_INDEX ValueCellToRelease = HCELL_NIL, CellToRelease = HCELL_NIL;
714 BOOLEAN IsSmall;
715 ULONG_PTR CompareResult;
716 PAGED_CODE();
717
718 /* Check if this is a symlink */
719 if (Kcb->Flags & KEY_SYM_LINK)
720 {
721 /* We need the exclusive lock */
722 if (!(CmpIsKcbLockedExclusive(Kcb)) &&
724 {
725 /* We need the exclusive lock */
727 }
728
729 /* Otherwise, get the key node */
730 KeyNode = (PCM_KEY_NODE)HvGetCell(Kcb->KeyHive, Kcb->KeyCell);
731 if (!KeyNode) return SearchFail;
732
733 /* Cleanup the KCB cache */
735
736 /* Sanity checks */
737 ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
738 ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
739
740 /* Set the value cache */
741 Kcb->ValueCache.Count = KeyNode->ValueList.Count;
742 Kcb->ValueCache.ValueList = KeyNode->ValueList.List;
743
744 /* Release the cell */
745 HvReleaseCell(Kcb->KeyHive, Kcb->KeyCell);
746 }
747
748 /* Do the search */
749 SearchResult = CmpFindValueByNameFromCache(Kcb,
750 ValueName,
751 &CachedValue,
752 &Index,
753 &Value,
754 &ValueCached,
755 &ValueCellToRelease);
756 if (SearchResult == SearchNeedExclusiveLock)
757 {
758 /* We need the exclusive lock */
760 ASSERT(ValueCellToRelease == HCELL_NIL);
761 ASSERT(Value == NULL);
762 goto Quickie;
763 }
764 else if (SearchResult == SearchSuccess)
765 {
766 /* Sanity check */
767 ASSERT(Value);
768
769 /* First of all, check if the key size and type matches */
770 if ((Type == Value->Type) &&
771 (DataSize == (Value->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE)))
772 {
773 /* Check if this is a small key */
774 IsSmall = (DataSize <= CM_KEY_VALUE_SMALL) ? TRUE: FALSE;
775 if (IsSmall)
776 {
777 /* Compare against the data directly */
778 Buffer = &Value->Data;
779 }
780 else
781 {
782 /* Do a search */
783 SearchResult = CmpGetValueDataFromCache(Kcb,
784 CachedValue,
786 ValueCached,
787 &Buffer,
788 &BufferAllocated,
789 &CellToRelease);
790 if (SearchResult != SearchSuccess)
791 {
792 /* Sanity checks */
793 ASSERT(Buffer == NULL);
794 ASSERT(BufferAllocated == FALSE);
795 goto Quickie;
796 }
797 }
798
799 /* Now check the data size */
800 if (DataSize)
801 {
802 /* Do the compare */
803 CompareResult = RtlCompareMemory(Buffer,
804 Data,
805 DataSize &
807 }
808 else
809 {
810 /* It's equal */
811 CompareResult = 0;
812 }
813
814 /* Now check if the compare wasn't equal */
815 if (CompareResult != DataSize) SearchResult = SearchFail;
816 }
817 else
818 {
819 /* The length or type isn't equal */
820 SearchResult = SearchFail;
821 }
822 }
823
824Quickie:
825 /* Release the value cell */
826 if (ValueCellToRelease) HvReleaseCell(Kcb->KeyHive, ValueCellToRelease);
827
828 /* Free the buffer */
829 if (BufferAllocated) CmpFree(Buffer, 0);
830
831 /* Free the cell */
832 if (CellToRelease) HvReleaseCell(Kcb->KeyHive, CellToRelease);
833
834 /* Return the search result */
835 return SearchResult;
836}
Type
Definition: Type.h:7
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:82
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:140
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cmdata.h:51
#define KEY_SYM_LINK
Definition: cmdata.h:34
VALUE_SEARCH_RETURN_TYPE NTAPI CmpFindValueByNameFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCUNICODE_STRING Name, OUT PCM_CACHED_VALUE **CachedValue, OUT ULONG *Index, OUT PCM_KEY_VALUE *Value, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:194
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueDataFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCELL_DATA ValueKey, IN BOOLEAN ValueIsCached, OUT PVOID *DataPointer, OUT PBOOLEAN Allocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:142
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
CHILD_LIST ValueList
Definition: cmdata.h:103

Referenced by CmSetValueKey().

◆ 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;
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 = (PCM_KEY_NODE)HvGetCell(MyKcb->KeyHive, MyKcb->KeyCell);
965 if (!KeyNode)
966 {
967 /* Failure */
968 CmpFree(KeyName, 0);
969 return NULL;
970 }
971 }
972 else
973 {
974 /* The key was deleted */
975 KeyNode = NULL;
976 DeletedKey = TRUE;
977 }
978
979 /* Get the pointer to the beginning of the current key name */
980 NameLength += (MyKcb->NameBlock->NameLength + 1) * sizeof(WCHAR);
981 TargetBuffer = &KeyName->Buffer[(KeyName->Length - NameLength) / sizeof(WCHAR)];
982
983 /* Add a separator */
984 TargetBuffer[0] = OBJ_NAME_PATH_SEPARATOR;
985
986 /* Add the name, but remember to go from the end to the beginning */
987 if (!MyKcb->NameBlock->Compressed)
988 {
989 /* Get the pointer to the name (from the keynode, if possible) */
990 if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
991 !KeyNode)
992 {
993 CurrentNameW = MyKcb->NameBlock->Name;
994 }
995 else
996 {
997 CurrentNameW = KeyNode->Name;
998 }
999
1000 /* Copy the name */
1001 for (i=0; i < MyKcb->NameBlock->NameLength; i++)
1002 {
1003 TargetBuffer[i+1] = *CurrentNameW;
1004 CurrentNameW++;
1005 }
1006 }
1007 else
1008 {
1009 /* Get the pointer to the name (from the keynode, if possible) */
1010 if ((MyKcb->Flags & (KEY_HIVE_ENTRY | KEY_HIVE_EXIT)) ||
1011 !KeyNode)
1012 {
1013 CurrentName = (PUCHAR)MyKcb->NameBlock->Name;
1014 }
1015 else
1016 {
1017 CurrentName = (PUCHAR)KeyNode->Name;
1018 }
1019
1020 /* Copy the name */
1021 for (i=0; i < MyKcb->NameBlock->NameLength; i++)
1022 {
1023 TargetBuffer[i+1] = (WCHAR)*CurrentName;
1024 CurrentName++;
1025 }
1026 }
1027
1028 /* Release the cell, if needed */
1029 if (KeyNode) HvReleaseCell(MyKcb->KeyHive, MyKcb->KeyCell);
1030
1031 /* Go to the parent KCB */
1032 MyKcb = MyKcb->ParentKcb;
1033 }
1034
1035 /* Return resulting buffer (both UNICODE_STRING and
1036 its buffer following it) */
1037 return KeyName;
1038}
#define CM_KCB_KEY_NON_EXIST
Definition: cm.h:56
#define KEY_HIVE_EXIT
Definition: cmdata.h:31
#define KEY_HIVE_ENTRY
Definition: cmdata.h:32
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
PCM_NAME_CONTROL_BLOCK NameBlock
Definition: cm.h:275
ULONG ExtFlags
Definition: cm.h:257
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
BOOLEAN Compressed
Definition: cm.h:233
USHORT NameLength
Definition: cm.h:242
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:243
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by CmpQueryKeyName().

◆ CmpCopyCell()

HCELL_INDEX NTAPI CmpCopyCell ( IN PHHIVE  SourceHive,
IN HCELL_INDEX  SourceCell,
IN PHHIVE  DestinationHive,
IN HSTORAGE_TYPE  StorageType 
)

Definition at line 376 of file cmvalue.c.

380{
381 PCELL_DATA SourceData;
382 PCELL_DATA DestinationData = NULL;
383 HCELL_INDEX DestinationCell = HCELL_NIL;
385
386 PAGED_CODE();
387
388 /* Get the data and the size of the source cell */
389 SourceData = HvGetCell(SourceHive, SourceCell);
390 DataSize = HvGetCellSize(SourceHive, SourceData);
391
392 /* Allocate a new cell in the destination hive */
393 DestinationCell = HvAllocateCell(DestinationHive,
394 DataSize,
395 StorageType,
396 HCELL_NIL);
397 if (DestinationCell == HCELL_NIL) goto Cleanup;
398
399 /* Get the data of the destination cell */
400 DestinationData = HvGetCell(DestinationHive, DestinationCell);
401
402 /* Copy the data from the source cell to the destination cell */
403 RtlMoveMemory(DestinationData, SourceData, DataSize);
404
405Cleanup:
406
407 /* Release the cells */
408 if (DestinationData) HvReleaseCell(DestinationHive, DestinationCell);
409 if (SourceData) HvReleaseCell(SourceHive, SourceCell);
410
411 /* Return the destination cell index */
412 return DestinationCell;
413}
LONG CMAPI HvGetCellSize(PHHIVE RegistryHive, PVOID Cell)
HCELL_INDEX CMAPI HvAllocateCell(PHHIVE RegistryHive, ULONG Size, HSTORAGE_TYPE Storage, IN HCELL_INDEX Vicinity)
static const WCHAR Cleanup[]
Definition: register.c:80
long LONG
Definition: pedump.c:60
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by CmpCopyValue(), and CmpDeepCopyKeyInternal().

◆ CmpCreateEvent()

NTSTATUS NTAPI CmpCreateEvent ( IN EVENT_TYPE  EventType,
OUT PHANDLE  EventHandle,
OUT PKEVENT Event 
)

Definition at line 19 of file cmwraprs.c.

22{
25
26 /* Create the event */
28 NULL,
30 NULL,
31 NULL);
32 Status = ZwCreateEvent(EventHandle,
36 FALSE);
37 if (!NT_SUCCESS(Status)) return Status;
38
39 /* Get a pointer to the object itself */
42 NULL,
44 (PVOID*)Event,
45 NULL);
47
48 /* Return status */
49 return Status;
50}
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ EVENT_TYPE EventType
Definition: exfuncs.h:167
_Out_ PHANDLE EventHandle
Definition: iofuncs.h:857

Referenced by CmpOpenHiveFiles().

◆ 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;
663 UNICODE_STRING NodeName;
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 */
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 */
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;
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 */
787 Kcb->ExtFlags &= ~CM_KCB_INVALID_CACHED_INFO;
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 */
830 Kcb->NameBlock = CmpGetNameControlBlock(&NodeName);
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}
#define CMP_CREATE_FAKE_KCB
Definition: cm.h:83
#define CMP_LOCK_HASHES_FOR_KCB
Definition: cm.h:84
#define CM_KCB_SIGNATURE
Definition: cm.h:46
#define ASSERT_KCB_VALID(k)
Definition: cm_x.h:76
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:179
PCM_KEY_CONTROL_BLOCK NTAPI CmpAllocateKeyControlBlock(VOID)
Definition: cmalloc.c:111
PCM_KEY_CONTROL_BLOCK NTAPI CmpInsertKeyHash(IN PCM_KEY_HASH KeyHash, IN BOOLEAN IsFake)
Definition: cmkcbncb.c:109
PCM_NAME_CONTROL_BLOCK NTAPI CmpGetNameControlBlock(IN PUNICODE_STRING NodeName)
Definition: cmkcbncb.c:148
BOOLEAN NTAPI CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:357
VOID NTAPI InitializeKCBKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:641
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
ULONG Count
Definition: cm.h:199
ULONG ValueList
Definition: cm.h:202
ULONG TotalLevels
Definition: cm.h:261
USHORT KcbMaxValueNameLen
Definition: cm.h:293
ULONG DelayedCloseIndex
Definition: cm.h:260
ULONG KcbMaxValueDataLen
Definition: cm.h:294
CM_KEY_HASH KeyHash
Definition: cm.h:265
ULONG RefCount
Definition: cm.h:254
LARGE_INTEGER KcbLastWriteTime
Definition: cm.h:291
ULONG Signature
Definition: cm.h:253
USHORT KcbMaxNameLen
Definition: cm.h:292
ULONG InDelayClose
Definition: cm.h:302
ULONG SubKeyCount
Definition: cm.h:282
CACHED_CHILD_LIST ValueCache
Definition: cm.h:277

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

◆ CmpCreateLinkNode()

NTSTATUS NTAPI CmpCreateLinkNode ( IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN PACCESS_STATE  AccessState,
IN UNICODE_STRING  Name,
IN KPROCESSOR_MODE  AccessMode,
IN ULONG  CreateOptions,
IN PCM_PARSE_CONTEXT  Context,
IN PCM_KEY_CONTROL_BLOCK  ParentKcb,
OUT PVOID Object 
)

Definition at line 727 of file cmparse.c.

736{
738 HCELL_INDEX KeyCell, LinkCell, ChildCell;
739 PCM_KEY_BODY KeyBody;
741 PCM_KEY_NODE KeyNode;
742 PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb;
743
744 /* Link nodes only allowed on the master */
745 if (Hive != &CmiVolatileHive->Hive)
746 {
747 /* Fail */
748 DPRINT1("Invalid link node attempt\n");
750 }
751
752 /* Check if the parent is being deleted */
753 if (ParentKcb->Delete)
754 {
755 /* It is, quit */
756 ASSERT(FALSE);
758 goto Exit;
759 }
760
761 /* Allocate a link node */
762 LinkCell = HvAllocateCell(Hive,
764 CmpNameSize(Hive, &Name),
765 Stable,
766 HCELL_NIL);
767 if (LinkCell == HCELL_NIL)
768 {
769 /* Fail */
771 goto Exit;
772 }
773
774 /* Get the key cell */
775 KeyCell = Context->ChildHive.KeyCell;
776 if (KeyCell != HCELL_NIL)
777 {
778 /* Hive exists! */
779 ChildCell = KeyCell;
780
781 /* Get the node data */
782 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
783 if (!KeyNode)
784 {
785 /* Fail */
786 ASSERT(FALSE);
788 goto Exit;
789 }
790
791 /* Fill out the data */
792 KeyNode->Parent = LinkCell;
793 KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
794 HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
795
796 /* Now open the key cell */
797 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, KeyCell);
798 if (!KeyNode)
799 {
800 /* Fail */
801 ASSERT(FALSE);
803 goto Exit;
804 }
805
806 /* Open the parent */
807 Status = CmpDoOpen(Context->ChildHive.KeyHive,
808 KeyCell,
809 KeyNode,
813 NULL,
814 0,
815 &Kcb,
816 &Name,
817 Object);
818 HvReleaseCell(Context->ChildHive.KeyHive, KeyCell);
819 }
820 else
821 {
822 /* Do the actual create operation */
823 Status = CmpDoCreateChild(Context->ChildHive.KeyHive,
824 Cell,
825 NULL,
827 &Name,
829 Context,
830 ParentKcb,
832 &ChildCell,
833 Object);
834 if (NT_SUCCESS(Status))
835 {
836 /* Setup root pointer */
837 Context->ChildHive.KeyHive->BaseBlock->RootCell = ChildCell;
838 }
839 }
840
841 /* Check if open or create suceeded */
842 if (NT_SUCCESS(Status))
843 {
844 /* Mark the cell dirty */
845 HvMarkCellDirty(Context->ChildHive.KeyHive, ChildCell, FALSE);
846
847 /* Get the key node */
848 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
849 if (!KeyNode)
850 {
851 /* Fail */
852 ASSERT(FALSE);
854 goto Exit;
855 }
856
857 /* Release it */
858 HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
859
860 /* Set the parent and flags */
861 KeyNode->Parent = LinkCell;
862 KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
863
864 /* Get the link node */
865 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, LinkCell);
866 if (!KeyNode)
867 {
868 /* Fail */
869 ASSERT(FALSE);
871 goto Exit;
872 }
873
874 /* Set it up */
876 KeyNode->Flags = KEY_HIVE_EXIT | KEY_NO_DELETE;
877 KeyNode->Parent = Cell;
878 KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, &Name);
879 if (KeyNode->NameLength < Name.Length) KeyNode->Flags |= KEY_COMP_NAME;
881 KeyNode->LastWriteTime = TimeStamp;
882
883 /* Clear out the rest */
884 KeyNode->SubKeyCounts[Stable] = 0;
885 KeyNode->SubKeyCounts[Volatile] = 0;
886 KeyNode->SubKeyLists[Stable] = HCELL_NIL;
887 KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
888 KeyNode->ValueList.Count = 0;
889 KeyNode->ValueList.List = HCELL_NIL;
890 KeyNode->ClassLength = 0;
891
892 /* Reference the root node */
893 KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
894 KeyNode->ChildHiveReference.KeyCell = ChildCell;
895 HvReleaseCell(Hive, LinkCell);
896
897 /* Get the parent node */
898 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
899 if (!KeyNode)
900 {
901 /* Fail */
902 ASSERT(FALSE);
904 goto Exit;
905 }
906
907 /* Now add the subkey */
908 if (!CmpAddSubKey(Hive, Cell, LinkCell))
909 {
910 /* Failure! We don't handle this yet! */
911 ASSERT(FALSE);
912 }
913
914 /* Get the key body */
915 KeyBody = (PCM_KEY_BODY)*Object;
916
917 /* Sanity checks */
918 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
919 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
920 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
921
922 /* Update the timestamp */
924 KeyNode->LastWriteTime = TimeStamp;
925 KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
926
927 /* Check if we need to update name maximum */
928 if (KeyNode->MaxNameLen < Name.Length)
929 {
930 /* Do it */
931 KeyNode->MaxNameLen = Name.Length;
932 KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name.Length;
933 }
934
935 /* Check if we need to update class length maximum */
936 if (KeyNode->MaxClassLen < Context->Class.Length)
937 {
938 /* Update it */
939 KeyNode->MaxClassLen = Context->Class.Length;
940 }
941
942 /* Release the cell */
943 HvReleaseCell(Hive, Cell);
944 }
945 else
946 {
947 /* Release the link cell */
948 HvReleaseCell(Hive, LinkCell);
949 }
950
951Exit:
952 /* Release the flusher locks and return status */
953 return Status;
954}
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define CM_LINK_NODE_SIGNATURE
Definition: cmdata.h:22
BOOLEAN NTAPI CmpAddSubKey(IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child)
Definition: cmindex.c:1465
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PCUNICODE_STRING Source)
Definition: cmname.c:21
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PCUNICODE_STRING Name)
Definition: cmname.c:74
NTSTATUS NTAPI CmpDoOpen(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PCM_KEY_NODE Node, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN PCM_PARSE_CONTEXT Context OPTIONAL, IN ULONG ControlFlags, IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb, IN PUNICODE_STRING KeyName, OUT PVOID *Object)
Definition: cmparse.c:558
NTSTATUS NTAPI CmpDoCreateChild(IN PHHIVE Hive, IN HCELL_INDEX ParentCell, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN ULONG Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)
Definition: cmparse.c:204
SECURITY_INTEGER TimeStamp
Definition: sspi.h:78
static void Exit(void)
Definition: sock.c:1330
USHORT Signature
Definition: cmdata.h:92
CM_KEY_REFERENCE ChildHiveReference
Definition: cmdata.h:105
HCELL_INDEX Parent
Definition: cmdata.h:96
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG MaxNameLen
Definition: cmdata.h:109
USHORT NameLength
Definition: cmdata.h:114
USHORT ClassLength
Definition: cmdata.h:115
ULONG MaxClassLen
Definition: cmdata.h:110
USHORT Flags
Definition: cmdata.h:93
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
PHHIVE KeyHive
Definition: cmdata.h:84
HCELL_INDEX KeyCell
Definition: cmdata.h:83
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:118
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by CmpParseKey().

◆ CmpDeepCopyKey()

NTSTATUS NTAPI CmpDeepCopyKey ( IN PHHIVE  SourceHive,
IN HCELL_INDEX  SrcKeyCell,
IN PHHIVE  DestinationHive,
IN HSTORAGE_TYPE  StorageType,
OUT PHCELL_INDEX DestKeyCell  OPTIONAL 
)

Definition at line 2627 of file cmapi.c.

2632{
2633 /* Call the internal function */
2634 return CmpDeepCopyKeyInternal(SourceHive,
2635 SrcKeyCell,
2636 DestinationHive,
2637 HCELL_NIL,
2638 StorageType,
2639 DestKeyCell);
2640}
static NTSTATUS CmpDeepCopyKeyInternal(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HCELL_INDEX Parent, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2451

Referenced by CmSaveKey(), and CmSaveMergedKeys().

◆ CmpDelayDerefKeyControlBlock()

VOID NTAPI CmpDelayDerefKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 286 of file cmdelay.c.

287{
288 LONG OldRefCount, NewRefCount;
291 PAGED_CODE();
293 "%s - Dereferencing KCB: %p\n", __FUNCTION__, Kcb);
294
295 /* Get the previous reference count */
296 OldRefCount = *(PLONG)&Kcb->RefCount;
297 NewRefCount = OldRefCount - 1;
298 if (((NewRefCount & 0xFFFF) > 0) &&
299 (InterlockedCompareExchange((PLONG)&Kcb->RefCount,
300 NewRefCount,
301 OldRefCount) == OldRefCount))
302 {
303 /* KCB still had references, so we're done */
304 return;
305 }
306
307 /* Allocate a delay item */
309 if (!Entry) return;
310
311 /* Set the KCB */
312 Entry->Kcb = Kcb;
313
314 /* Acquire the delayed deref table lock */
316
317 /* Insert the entry into the list */
319
320 /* Check if we need to enable anything */
322 {
323 /* Yes, we have no work item, setup the interval */
325 Timeout.QuadPart = CmpDelayDerefKCBIntervalInSeconds * -10000000;
327 }
328
329 /* Release the table lock */
331}
#define CMTRACE(x, fmt,...)
Definition: cm.h:40
#define CM_REFERENCE_DEBUG
Definition: cm.h:26
KTIMER CmpDelayDerefKCBTimer
Definition: cmdelay.c:34
KGUARDED_MUTEX CmpDelayDerefKCBLock
Definition: cmdelay.c:29
ULONG CmpDelayDerefKCBIntervalInSeconds
Definition: cmdelay.c:32
BOOLEAN CmpDelayDerefKCBWorkItemActive
Definition: cmdelay.c:30
LIST_ENTRY CmpDelayDerefKCBListHead
Definition: cmdelay.c:31
KDPC CmpDelayDerefKCBDpc
Definition: cmdelay.c:33