ReactOS 0.4.15-dev-7924-g5949c20
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_HASH_CACHE_STACK
 
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_LOCK_KCB_ARRAY_EXCLUSIVE   0x1
 
#define CMP_LOCK_KCB_ARRAY_SHARED   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))
 
#define CMP_SUBKEY_LEVELS_DEPTH_LIMIT   32
 
#define CMP_KCBS_IN_ARRAY_LIMIT   (CMP_SUBKEY_LEVELS_DEPTH_LIMIT + 2)
 

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_HASH_CACHE_STACK CM_HASH_CACHE_STACK
 
typedef struct _CM_HASH_CACHE_STACKPCM_HASH_CACHE_STACK
 
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)
 
NTSTATUS CmpAssignSecurityDescriptor (IN PCM_KEY_CONTROL_BLOCK Kcb, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
 
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)
 
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_opt_ PVOID HiveData, _In_ HANDLE Primary, _In_ HANDLE Log, _In_ HANDLE External, _In_ HANDLE Alternate, _In_opt_ PCUNICODE_STRING FileName, _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 CmpUnLockKcbArray (_In_ PULONG LockedKcbs)
 Unlocks a number of KCBs provided by a KCB array.
 
PULONG NTAPI CmpBuildAndLockKcbArray (_In_ PCM_HASH_CACHE_STACK HashCacheStack, _In_ ULONG KcbLockFlags, _In_ PCM_KEY_CONTROL_BLOCK Kcb, _Inout_ PULONG OuterStackArray, _In_ ULONG TotalRemainingSubkeys, _In_ ULONG MatchRemainSubkeyLevel)
 Builds an array of KCBs and locks them. Whether these KCBs are locked exclusively or in shared mode by the calling thread, is specified by the KcbLockFlags parameter. The array is sorted.
 
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, IN PULONG KcbsLocked, 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 LockHeldExclusively, _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
 
BOOLEAN HvShutdownComplete
 

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 125 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 123 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 118 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_KCBS_IN_ARRAY_LIMIT

#define CMP_KCBS_IN_ARRAY_LIMIT   (CMP_SUBKEY_LEVELS_DEPTH_LIMIT + 2)

Definition at line 132 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_LOCK_KCB_ARRAY_EXCLUSIVE

#define CMP_LOCK_KCB_ARRAY_EXCLUSIVE   0x1

Definition at line 101 of file cm.h.

◆ CMP_LOCK_KCB_ARRAY_SHARED

#define CMP_LOCK_KCB_ARRAY_SHARED   0x2

Definition at line 102 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_SUBKEY_LEVELS_DEPTH_LIMIT

#define CMP_SUBKEY_LEVELS_DEPTH_LIMIT   32

Definition at line 131 of file cm.h.

◆ CMP_UNLOCK_KCB_LOCKED

#define CMP_UNLOCK_KCB_LOCKED   0x1

Definition at line 107 of file cm.h.

◆ CMP_UNLOCK_REGISTRY_LOCKED

#define CMP_UNLOCK_REGISTRY_LOCKED   0x2

Definition at line 108 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 113 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_HASH_CACHE_STACK

◆ 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_HASH_CACHE_STACK

◆ 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 137 of file cm.h.

138{
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
@ SearchSuccess
Definition: cm.h:139
@ SearchNeedExclusiveLock
Definition: cm.h:140
@ SearchFail
Definition: cm.h:141

Function Documentation

◆ CmDeleteKey()

NTSTATUS NTAPI CmDeleteKey ( IN PCM_KEY_BODY  KeyBody)

Definition at line 1823 of file cmapi.c.

1824{
1826 PHHIVE Hive;
1828 HCELL_INDEX Cell, ParentCell;
1830
1831 /* Acquire hive lock */
1833
1834 /* Get the kcb */
1835 Kcb = KeyBody->KeyControlBlock;
1836
1837 /* Don't allow deleting the root */
1838 if (!Kcb->ParentKcb)
1839 {
1840 /* Fail */
1842 return STATUS_CANNOT_DELETE;
1843 }
1844
1845 /* Lock parent and child */
1847
1848 /* Check if we're already being deleted */
1849 if (Kcb->Delete)
1850 {
1851 /* Don't do it twice */
1853 goto Quickie;
1854 }
1855
1856 /* Get the hive and node */
1857 Hive = Kcb->KeyHive;
1858 Cell = Kcb->KeyCell;
1859
1860 /* Lock flushes */
1862
1863 /* Get the key node */
1864 Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1865 ASSERT(Node);
1866
1867 /* Sanity check */
1868 ASSERT(Node->Flags == Kcb->Flags);
1869
1870 /* Check if we don't have any children */
1871 if (!(Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile]) &&
1872 !(Node->Flags & KEY_NO_DELETE))
1873 {
1874 /* Send notification to registered callbacks */
1875 CmpReportNotify(Kcb, Hive, Cell, REG_NOTIFY_CHANGE_NAME);
1876
1877 /* Get the parent and free the cell */
1878 ParentCell = Node->Parent;
1879 Status = CmpFreeKeyByCell(Hive, Cell, TRUE);
1880 if (NT_SUCCESS(Status))
1881 {
1882 /* Flush any notifications */
1884
1885 /* Clean up information we have on the subkey */
1887
1888 /* Get the parent node */
1889 Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
1890 if (Parent)
1891 {
1892 /* Update the maximum name length */
1893 Kcb->ParentKcb->KcbMaxNameLen = (USHORT)Parent->MaxNameLen;
1894
1895 /* Make sure we're dirty */
1896 ASSERT(HvIsCellDirty(Hive, ParentCell));
1897
1898 /* Update the write time */
1899 KeQuerySystemTime(&Parent->LastWriteTime);
1900 Kcb->ParentKcb->KcbLastWriteTime = Parent->LastWriteTime;
1901
1902 /* Release the cell */
1903 HvReleaseCell(Hive, ParentCell);
1904 }
1905
1906 /* Set the KCB in delete mode and remove it */
1907 Kcb->Delete = TRUE;
1909
1910 /* Clear the cell */
1911 Kcb->KeyCell = HCELL_NIL;
1912 }
1913 }
1914 else
1915 {
1916 /* Fail */
1918 }
1919
1920 /* Release the cell */
1921 HvReleaseCell(Hive, Cell);
1922
1923 /* Release flush lock */
1925
1926 /* Release the KCB locks */
1927Quickie:
1928 CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
1929
1930 /* Release hive lock */
1932 return Status;
1933}
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:1368
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:460
BOOLEAN CMAPI HvIsCellDirty(IN PHHIVE Hive, IN HCELL_INDEX Cell)
Definition: hivecell.c:153
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
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:2056
VOID NTAPI CmpAcquireTwoKcbLocksExclusiveByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2079
VOID NTAPI CmpReleaseTwoKcbLockByKey(IN ULONG ConvKey1, IN ULONG ConvKey2)
Definition: cmsysini.c:2108
VOID NTAPI CmpLockRegistry(VOID)
Definition: cmsysini.c:1970
VOID NTAPI CmpLockHiveFlusherShared(IN PCMHIVE Hive)
Definition: cmsysini.c:2017
VOID NTAPI CmpUnlockHiveFlusher(IN PCMHIVE Hive)
Definition: cmsysini.c:2028
#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:128
@ Stable
Definition: hivedata.h:127
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#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:316
PHHIVE KeyHive
Definition: cm.h:285
struct _CM_KEY_CONTROL_BLOCK * ParentKcb
Definition: cm.h:289
HCELL_INDEX KeyCell
Definition: cm.h:286
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 915 of file cmapi.c.

917{
919 PHHIVE Hive;
921 HCELL_INDEX ChildCell, Cell;
924 ULONG ChildIndex;
926
927 /* Acquire hive lock */
929
930 /* Lock KCB exclusively */
932
933 /* Don't touch deleted keys */
934 if (Kcb->Delete)
935 {
936 /* Undo everything */
939 return STATUS_KEY_DELETED;
940 }
941
942 /* Get the hive and the cell index */
943 Hive = Kcb->KeyHive;
944 Cell = Kcb->KeyCell;
945
946 /* Lock flushes */
948
949 /* Get the parent key node */
950 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
951 ASSERT(Parent);
952
953 /* Get the value list and check if it has any entries */
954 ChildList = &Parent->ValueList;
955 if (ChildList->Count)
956 {
957 /* Try to find this value */
959 ChildList,
960 &ValueName,
961 &ChildIndex,
962 &ChildCell);
963 if (!Result)
964 {
965 /* Fail */
967 goto Quickie;
968 }
969
970 /* Value not found, return error */
971 if (ChildCell == HCELL_NIL) goto Quickie;
972
973 /* We found the value, mark all relevant cells dirty */
974 if (!(HvMarkCellDirty(Hive, Cell, FALSE) &&
975 HvMarkCellDirty(Hive, Parent->ValueList.List, FALSE) &&
976 HvMarkCellDirty(Hive, ChildCell, FALSE)))
977 {
978 /* Not enough log space, fail */
980 goto Quickie;
981 }
982
983 /* Get the key value */
984 Value = (PCM_KEY_VALUE)HvGetCell(Hive, ChildCell);
985 ASSERT(Value);
986
987 /* Mark it and all related data as dirty */
988 if (!CmpMarkValueDataDirty(Hive, Value))
989 {
990 /* Not enough log space, fail */
992 goto Quickie;
993 }
994
995 /* Sanity checks */
996 ASSERT(HvIsCellDirty(Hive, Parent->ValueList.List));
997 ASSERT(HvIsCellDirty(Hive, ChildCell));
998
999 /* Remove the value from the child list */
1000 Status = CmpRemoveValueFromList(Hive, ChildIndex, ChildList);
1001 if (!NT_SUCCESS(Status))
1002 {
1003 /* Set known error */
1005 goto Quickie;
1006 }
1007
1008 /* Remove the value and its data itself */
1009 if (!CmpFreeValue(Hive, ChildCell))
1010 {
1011 /* Failed to free the value, fail */
1013 goto Quickie;
1014 }
1015
1016 /* Set the last write time */
1017 KeQuerySystemTime(&Parent->LastWriteTime);
1018 Kcb->KcbLastWriteTime = Parent->LastWriteTime;
1019
1020 /* Sanity check */
1021 ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
1022 ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
1023 ASSERT(HvIsCellDirty(Hive, Cell));
1024
1025 /* Check if the value list is empty now */
1026 if (!Parent->ValueList.Count)
1027 {
1028 /* Then clear key node data */
1029 Parent->MaxValueNameLen = 0;
1030 Parent->MaxValueDataLen = 0;
1031 Kcb->KcbMaxValueNameLen = 0;
1032 Kcb->KcbMaxValueDataLen = 0;
1033 }
1034
1035 /* Cleanup the value cache */
1037
1038 /* Sanity checks */
1039 ASSERT(!CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList));
1040 ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
1041
1042 /* Set the value cache */
1043 Kcb->ValueCache.Count = ChildList->Count;
1044 Kcb->ValueCache.ValueList = ChildList->List;
1045
1046 /* Notify registered callbacks */
1048
1049 /* Change default Status to success */
1051 }
1052
1053Quickie:
1054 /* Release the parent cell, if any */
1055 if (Parent) HvReleaseCell(Hive, Cell);
1056
1057 /* Check if we had a value */
1058 if (Value)
1059 {
1060 /* Release the child cell */
1061 ASSERT(ChildCell != HCELL_NIL);
1062 HvReleaseCell(Hive, ChildCell);
1063 }
1064
1065 /* Release locks */
1067 CmpReleaseKcbLock(Kcb);
1069 return Status;
1070}
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:116
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:34
FORCEINLINE VOID CmpReleaseKcbLock(PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cm_x.h:185
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:409

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 1734 of file cmapi.c.

1740{
1742 PHHIVE Hive;
1744 HCELL_INDEX ChildCell;
1745 HV_TRACK_CELL_REF CellReferences = {0};
1746
1747 /* Acquire hive lock */
1749
1750 /* Lock the KCB shared */
1752
1753 /* Don't touch deleted keys */
1754 if (Kcb->Delete)
1755 {
1756 /* Undo everything */
1758 goto Quickie;
1759 }
1760
1761 /* Get the hive and parent */
1762 Hive = Kcb->KeyHive;
1763 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1764 ASSERT(Parent);
1765
1766 /* Get the child cell */
1767 ChildCell = CmpFindSubKeyByNumber(Hive, Parent, Index);
1768
1769 /* Release the parent cell */
1770 HvReleaseCell(Hive, Kcb->KeyCell);
1771
1772 /* Check if we found the child */
1773 if (ChildCell == HCELL_NIL)
1774 {
1775 /* We didn't, fail */
1777 goto Quickie;
1778 }
1779
1780 /* Now get the actual child node */
1781 Child = (PCM_KEY_NODE)HvGetCell(Hive, ChildCell);
1782 ASSERT(Child);
1783
1784 /* Track references */
1785 if (!HvTrackCellRef(&CellReferences, Hive, ChildCell))
1786 {
1787 /* Can't allocate memory for tracking */
1789 goto Quickie;
1790 }
1791
1792 /* Data can be user-mode, use SEH */
1793 _SEH2_TRY
1794 {
1795 /* Query the data requested */
1796 Status = CmpQueryKeyData(Hive,
1797 Child,
1799 KeyInformation,
1800 Length,
1801 ResultLength);
1802 }
1804 {
1805 /* Fail with exception code */
1807 _SEH2_YIELD(goto Quickie);
1808 }
1809 _SEH2_END;
1810
1811Quickie:
1812 /* Release references */
1813 HvReleaseFreeCellRefArray(&CellReferences);
1814
1815 /* Release locks */
1816 CmpReleaseKcbLock(Kcb);
1818 return Status;
1819}
#define CmpAcquireKcbLockShared(k)
Definition: cm_x.h:145
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:375
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 1191 of file cmapi.c.

1197{
1199 PHHIVE Hive;
1201 HCELL_INDEX CellToRelease = HCELL_NIL, CellToRelease2 = HCELL_NIL;
1203 BOOLEAN IndexIsCached, ValueIsCached = FALSE;
1204 PCELL_DATA CellData;
1205 PCM_CACHED_VALUE *CachedValue;
1207 PAGED_CODE();
1208
1209 /* Acquire hive lock */
1211
1212 /* Lock the KCB shared */
1214
1215 /* Don't touch deleted keys */
1216DoAgain:
1217 if (Kcb->Delete)
1218 {
1219 /* Undo everything */
1220 CmpReleaseKcbLock(Kcb);
1222 return STATUS_KEY_DELETED;
1223 }
1224
1225 /* Get the hive and parent */
1226 Hive = Kcb->KeyHive;
1227 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Kcb->KeyCell);
1228 ASSERT(Parent);
1229
1230 /* FIXME: Lack of cache? */
1231 if (Kcb->ValueCache.Count != Parent->ValueList.Count)
1232 {
1233 DPRINT1("HACK: Overriding value cache count\n");
1234 Kcb->ValueCache.Count = Parent->ValueList.Count;
1235 }
1236
1237 /* Make sure the index is valid */
1238 if (Index >= Kcb->ValueCache.Count)
1239 {
1240 /* Release the cell and fail */
1241 HvReleaseCell(Hive, Kcb->KeyCell);
1243 goto Quickie;
1244 }
1245
1246 /* We don't deal with this yet */
1247 if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
1248 {
1249 /* Shouldn't happen */
1250 ASSERT(FALSE);
1251 }
1252
1253 /* Find the value list */
1255 &CellData,
1256 &IndexIsCached,
1257 &CellToRelease);
1259 {
1260 /* Check if we need an exclusive lock */
1261 ASSERT(CellToRelease == HCELL_NIL);
1262 HvReleaseCell(Hive, Kcb->KeyCell);
1263
1264 /* Try with exclusive KCB lock */
1266 goto DoAgain;
1267 }
1268 else if (Result != SearchSuccess)
1269 {
1270 /* Sanity check */
1271 ASSERT(CellData == NULL);
1272
1273 /* Release the cell and fail */
1275 goto Quickie;
1276 }
1277
1278 /* Now get the key value */
1280 CellData,
1281 Index,
1282 &CachedValue,
1283 &ValueData,
1284 IndexIsCached,
1285 &ValueIsCached,
1286 &CellToRelease2);
1288 {
1289 /* Cleanup state */
1290 ASSERT(CellToRelease2 == HCELL_NIL);
1291 if (CellToRelease)
1292 {
1293 HvReleaseCell(Hive, CellToRelease);
1294 CellToRelease = HCELL_NIL;
1295 }
1296 HvReleaseCell(Hive, Kcb->KeyCell);
1297
1298 /* Try with exclusive KCB lock */
1300 goto DoAgain;
1301 }
1302 else if (Result != SearchSuccess)
1303 {
1304 /* Sanity check */
1305 ASSERT(ValueData == NULL);
1306
1307 /* Release the cells and fail */
1309 goto Quickie;
1310 }
1311
1312 /* User data, need SEH */
1313 _SEH2_TRY
1314 {
1315 /* Query the information requested */
1317 CachedValue,
1318 ValueData,
1319 ValueIsCached,
1321 KeyValueInformation,
1322 Length,
1324 &Status);
1326 {
1327 /* Cleanup state */
1328 if (CellToRelease2) HvReleaseCell(Hive, CellToRelease2);
1329 HvReleaseCell(Hive, Kcb->KeyCell);
1330 if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
1331
1332 /* Try with exclusive KCB lock */
1334 _SEH2_YIELD(goto DoAgain);
1335 }
1336 }
1338 {
1339 /* Get exception code */
1341 }
1342 _SEH2_END;
1343
1344Quickie:
1345 /* If we have a cell to release, do so */
1346 if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1347
1348 /* Release the parent cell */
1349 HvReleaseCell(Hive, Kcb->KeyCell);
1350
1351 /* If we have a cell to release, do so */
1352 if (CellToRelease2 != HCELL_NIL) HvReleaseCell(Hive, CellToRelease2);
1353
1354 /* Release locks */
1355 CmpReleaseKcbLock(Kcb);
1357 return Status;
1358}
#define PAGED_CODE()
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:205
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 1937 of file cmapi.c.

1939{
1940 PCMHIVE CmHive;
1941#if DBG
1942 CM_CHECK_REGISTRY_STATUS CheckStatus;
1943#endif
1945 PHHIVE Hive;
1946
1947 /* Ignore flushes until we're ready */
1948 if (CmpNoWrite) return STATUS_SUCCESS;
1949
1950 /* Get the hives */
1951 Hive = Kcb->KeyHive;
1952 CmHive = (PCMHIVE)Hive;
1953
1954 /* Check if this is the master hive */
1955 if (CmHive == CmiVolatileHive)
1956 {
1957 /* Flush all the hives instead */
1959 }
1960 else
1961 {
1962#if DBG
1963 /* Make sure the registry hive we're going to flush is OK */
1965 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
1966#endif
1967
1968 /* Don't touch the hive */
1970
1971 ASSERT(CmHive->ViewLock);
1974
1975 /* Will the hive shrink? */
1976 if (HvHiveWillShrink(Hive))
1977 {
1978 /* I don't believe the current Hv does shrinking */
1979 ASSERT(FALSE);
1980 // CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK_OR_LOADING(CmHive);
1981 }
1982 else
1983 {
1984 /* Now we can release views */
1985 ASSERT(CmHive->ViewLock);
1986 // CMP_ASSERT_VIEW_LOCK_OWNED(CmHive);
1988 (CmHive->HiveIsLoading == TRUE) ||
1989 (CmHive->ViewLockOwner == KeGetCurrentThread()) ||
1991 CmHive->ViewLockOwner = NULL;
1993 }
1994
1995 /* Flush only this hive */
1996 if (!HvSyncHive(Hive))
1997 {
1998 /* Fail */
2000 }
2001
2002 /* Release the flush lock */
2003 CmpUnlockHiveFlusher(CmHive);
2004 }
2005
2006 /* Return the status */
2007 return Status;
2008}
BOOLEAN NTAPI CmpDoFlushAll(IN BOOLEAN ForceFlush)
Definition: cmapi.c:81
CM_CHECK_REGISTRY_STATUS NTAPI CmCheckRegistry(_In_ PCMHIVE RegistryHive, _In_ ULONG Flags)
Checks the registry that is consistent and its contents valid and not corrupted. More specifically th...
Definition: cmcheck.c:1633
#define CM_CHECK_REGISTRY_DONT_PURGE_VOLATILES
Definition: cmlib.h:228
BOOLEAN CMAPI HvHiveWillShrink(IN PHHIVE RegistryHive)
BOOLEAN CMAPI HvSyncHive(PHHIVE RegistryHive)
#define CM_CHECK_REGISTRY_VALIDATE_HIVE
Definition: cmlib.h:231
#define CM_CHECK_REGISTRY_SUCCESS(StatusCode)
Definition: cmlib.h:281
struct _CMHIVE * PCMHIVE
ULONG CM_CHECK_REGISTRY_STATUS
Definition: cmlib.h:223
VOID NTAPI CmpLockHiveFlusherExclusive(IN PCMHIVE Hive)
Definition: cmsysini.c:2006
BOOLEAN CmpSpecialBootCondition
Definition: cmsysini.c:26
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:16
BOOLEAN NTAPI CmpTestRegistryLockExclusive(VOID)
Definition: cmsysini.c:1998
BOOLEAN CmpNoWrite
Definition: cmsysini.c:30
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:357
PKGUARDED_MUTEX ViewLock
Definition: cmlib.h:323
PKTHREAD ViewLockOwner
Definition: cmlib.h:324

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 ? (Length <= CM_KEY_VALUE_SMALL) : TRUE);
212
213 /* Copy the data in the buffer */
214 RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
215 }
216
217 /* Check if we should return the data type */
218 if (ControlVector->Type)
219 {
220 /* Return the type that we read */
221 *ControlVector->Type = ValueData->Type;
222 }
223 }
224 }
225
226 /* Return the size that we read */
227 if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
228
229 /* Go to the next entry */
230 ControlVector++;
231 }
232
233 /* Check if the ID is in the registry */
235 {
236 /* Read it */
240 }
241 else
242 {
243 /* Use EN_US by default */
245 }
246
247 /* Check if the ID Is in the registry */
249 {
250 /* Read it */
253 }
254 else
255 {
256 /* Otherwise, use the default */
258 }
259
260 /* Set the defaults for the Thread UI */
263}
PHHIVE SystemHive
Definition: registry.c:33
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)
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:395
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:317
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 1839 of file cmsysini.c.

1840{
1841 LIST_ENTRY DriverList;
1844 PCM_KEY_BODY KeyBody;
1845 PHHIVE Hive;
1846 HCELL_INDEX RootCell, ControlCell;
1849 PLIST_ENTRY NextEntry;
1850 ULONG i;
1851 PUNICODE_STRING* ServicePath = NULL;
1852 BOOLEAN Success, AutoSelect;
1854 PAGED_CODE();
1855
1856 /* Initialize the driver list */
1857 InitializeListHead(&DriverList);
1858
1859 /* Open the system hive key */
1860 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System");
1862 &KeyName,
1864 NULL,
1865 NULL);
1867 if (!NT_SUCCESS(Status)) return NULL;
1868
1869 /* Reference the key object to get the root hive/cell to access directly */
1873 KernelMode,
1874 (PVOID*)&KeyBody,
1875 NULL);
1876 if (!NT_SUCCESS(Status))
1877 {
1878 /* Fail */
1880 return NULL;
1881 }
1882
1883 /* Do all this under the registry lock */
1885
1886 /* Get the hive and key cell */
1887 Hive = KeyBody->KeyControlBlock->KeyHive;
1888 RootCell = KeyBody->KeyControlBlock->KeyCell;
1889
1890 /* Open the current control set key */
1891 RtlInitUnicodeString(&KeyName, L"Current");
1892 ControlCell = CmpFindControlSet(Hive, RootCell, &KeyName, &AutoSelect);
1893 if (ControlCell == HCELL_NIL) goto EndPath;
1894
1895 /* Find all system drivers */
1896 Success = CmpFindDrivers(Hive, ControlCell, SystemLoad, NULL, &DriverList);
1897 if (!Success) goto EndPath;
1898
1899 /* Sort by group/tag */
1900 if (!CmpSortDriverList(Hive, ControlCell, &DriverList)) goto EndPath;
1901
1902 /* Remove circular dependencies (cycles) and sort */
1903 if (!CmpResolveDriverDependencies(&DriverList)) goto EndPath;
1904
1905 /* Loop the list to count drivers */
1906 for (i = 0, NextEntry = DriverList.Flink;
1907 NextEntry != &DriverList;
1908 i++, NextEntry = NextEntry->Flink);
1909
1910 /* Allocate the array */
1911 ServicePath = ExAllocatePool(NonPagedPool, (i + 1) * sizeof(PUNICODE_STRING));
1912 if (!ServicePath) KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1913
1914 /* Loop the driver list */
1915 for (i = 0, NextEntry = DriverList.Flink;
1916 NextEntry != &DriverList;
1917 i++, NextEntry = NextEntry->Flink)
1918 {
1919 /* Get the entry */
1921
1922 /* Allocate the path for the caller */
1923 ServicePath[i] = ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING));
1924 if (!ServicePath[i])
1925 {
1926 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1927 }
1928
1929 /* Duplicate the registry path */
1931 &DriverEntry->RegistryPath,
1932 ServicePath[i]);
1933 if (!NT_SUCCESS(Status))
1934 {
1935 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 2, 1, 0, 0);
1936 }
1937 }
1938
1939 /* Terminate the list */
1940 ServicePath[i] = NULL;
1941
1942EndPath:
1943 /* Free the driver list if we had one */
1944 if (!IsListEmpty(&DriverList)) CmpFreeDriverList(Hive, &DriverList);
1945
1946 /* Unlock the registry */
1948
1949 /* Close the key handle and dereference the object, then return the path */
1950 ObDereferenceObject(KeyBody);
1952 return ServicePath;
1953}
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:1957
POBJECT_TYPE CmpKeyObjectType
Definition: cmsysini.c:15
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:246
struct _CM_KEY_CONTROL_BLOCK * KeyControlBlock
Definition: cm.h:234
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:136
#define ExAcquireRundownProtection
Definition: ex.h:135
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 1621 of file cmsysini.c.

1622{
1627 PCMHIVE HardwareHive;
1629 PAGED_CODE();
1630
1631 /* Check if this is PE-boot */
1632 if (InitIsWinPEMode)
1633 {
1634 /* Set the registry in PE mode and load the system hives in shared mode */
1637 }
1638
1639 /* Initialize the hive list and lock */
1643
1644 /* Initialize registry lock */
1646
1647 /* Initialize the cache */
1649
1650 /* Initialize allocation and delayed dereferencing */
1654
1655 /* Initialize callbacks */
1657
1658 /* Initialize self healing */
1661
1662 /* Save the current process and lock the registry */
1664
1665 /* Create the key object types */
1667 if (!NT_SUCCESS(Status))
1668 {
1669 /* Bugcheck */
1670 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0);
1671 }
1672
1673 /* Build the master hive */
1678 NULL,
1679 NULL,
1680 NULL,
1681 NULL,
1682 NULL,
1683 NULL,
1685 if (!NT_SUCCESS(Status))
1686 {
1687 /* Bugcheck */
1688 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 2, Status, 0);
1689 }
1690
1691 /* Create the \REGISTRY key node */
1692 if (!CmpCreateRegistryRoot())
1693 {
1694 /* Bugcheck */
1695 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0);
1696 }
1697
1698 /* Create the default security descriptor */
1700
1701 /* Create '\Registry\Machine' key */
1702 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE");
1704 &KeyName,
1706 NULL,
1711 0,
1712 NULL,
1713 0,
1714 NULL);
1715 if (!NT_SUCCESS(Status))
1716 {
1717 /* Bugcheck */
1718 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 5, Status, 0);
1719 }
1720
1721 /* Close the handle */
1723
1724 /* Create '\Registry\User' key */
1725 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\USER");
1727 &KeyName,
1729 NULL,
1734 0,
1735 NULL,
1736 0,
1737 NULL);
1738 if (!NT_SUCCESS(Status))
1739 {
1740 /* Bugcheck */
1741 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 6, Status, 0);
1742 }
1743
1744 /* Close the handle */
1746
1747 /* After this point, do not allow creating keys in the master hive */
1749
1750 /* Initialize the system hive */
1752 {
1753 /* Bugcheck */
1754 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 7, 0, 0);
1755 }
1756
1757 /* Create the 'CurrentControlSet' link */
1759 if (!NT_SUCCESS(Status))
1760 {
1761 /* Bugcheck */
1762 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 8, Status, 0);
1763 }
1764
1765 /* Create the hardware hive */
1766 Status = CmpInitializeHive(&HardwareHive,
1770 NULL,
1771 NULL,
1772 NULL,
1773 NULL,
1774 NULL,
1775 NULL,
1777 if (!NT_SUCCESS(Status))
1778 {
1779 /* Bugcheck */
1780 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 11, Status, 0);
1781 }
1782
1783 /* Add the hive to the hive list */
1784 CmpMachineHiveList[0].CmHive = HardwareHive;
1785
1786 /* Attach it to the machine key */
1787 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\HARDWARE");
1789 NULL,
1790 HardwareHive,
1791 TRUE,
1793 if (!NT_SUCCESS(Status))
1794 {
1795 /* Bugcheck */
1796 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 12, Status, 0);
1797 }
1798
1799 /* Add to HiveList key */
1800 CmpAddToHiveFileList(HardwareHive);
1801
1802 /* Free the security descriptor */
1804
1805 /* Fill out the Hardware key with the ARC Data from the Loader */
1807 if (!NT_SUCCESS(Status))
1808 {
1809 /* Bugcheck */
1810 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 13, Status, 0);
1811 }
1812
1813 /* Initialize machine-dependent information into the registry */
1815 if (!NT_SUCCESS(Status))
1816 {
1817 /* Bugcheck */
1818 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 14, Status, 0);
1819 }
1820
1821 /* Initialize volatile registry settings */
1823 if (!NT_SUCCESS(Status))
1824 {
1825 /* Bugcheck */
1826 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 1, 15, Status, 0);
1827 }
1828
1829 /* Free the load options */
1831
1832 /* If we got here, all went well */
1833 return TRUE;
1834}
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:329
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:58
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:212
#define TAG_CMSD
Definition: cmlib.h:215
BOOLEAN NTAPI CmpCreateRegistryRoot(VOID)
Definition: cmsysini.c:1070
ERESOURCE CmpRegistryLock
Definition: cmsysini.c:18
NTSTATUS NTAPI CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, IN HANDLE RootDirectory, IN PCMHIVE RegistryHive, IN BOOLEAN Allocate, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: cmsysini.c:802
PEPROCESS CmpSystemProcess
Definition: cmsysini.c:23
NTSTATUS NTAPI CmpCreateObjectTypes(VOID)
Definition: cmsysini.c:980
NTSTATUS NTAPI CmpCreateControlSet(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:528
BOOLEAN NTAPI CmpInitializeSystemHive(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:869
BOOLEAN CmpNoVolatileCreates
Definition: cmsysini.c:34
LIST_ENTRY CmpHiveListHead
Definition: cmsysini.c:17
LIST_ENTRY CmpSelfHealQueueListHead
Definition: cmsysini.c:20
KGUARDED_MUTEX CmpSelfHealQueueLock
Definition: cmsysini.c:19
NTSTATUS NTAPI CmpSetSystemValues(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: cmsysini.c:401
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExInitializePushLock
Definition: ex.h:1013
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:1109
#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_opt_ PVOID HiveData, _In_ HANDLE Primary, _In_ HANDLE Log, _In_ HANDLE External, _In_ HANDLE Alternate, _In_opt_ PCUNICODE_STRING FileName, _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:411
_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 2012 of file cmapi.c.

2016{
2017 SECURITY_QUALITY_OF_SERVICE ServiceQos;
2018 SECURITY_CLIENT_CONTEXT ClientSecurityContext;
2021 PCMHIVE CmHive, LoadedHive;
2023 CM_PARSE_CONTEXT ParseContext;
2024
2025 /* Check if we have a trust key */
2026 if (KeyBody)
2027 {
2028 /* Fail */
2029 DPRINT("Trusted classes not yet supported\n");
2030 }
2031
2032 /* Build a service QoS for a security context */
2033 ServiceQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
2036 ServiceQos.EffectiveOnly = TRUE;
2038 &ServiceQos,
2039 FALSE,
2040 &ClientSecurityContext);
2041 if (!NT_SUCCESS(Status))
2042 {
2043 /* Fail */
2044 DPRINT1("Security context failed\n");
2045 return Status;
2046 }
2047
2048 /* Open the target key */
2049 RtlZeroMemory(&ParseContext, sizeof(ParseContext));
2050 ParseContext.CreateOperation = FALSE;
2051 Status = ObOpenObjectByName(TargetKey,
2053 KernelMode,
2054 NULL,
2055 KEY_READ,
2056 &ParseContext,
2057 &KeyHandle);
2059
2060 /* Open the hive */
2061 Status = CmpCmdHiveOpen(SourceFile,
2062 &ClientSecurityContext,
2063 &Allocate,
2064 &CmHive,
2066
2067 /* Get rid of the security context */
2068 SeDeleteClientSecurity(&ClientSecurityContext);
2069
2070 /* See if we failed */
2071 if (!NT_SUCCESS(Status))
2072 {
2073 /* See if the target already existed */
2074 if (KeyHandle)
2075 {
2076 /* Lock the registry */
2078
2079 /* Check if we are already loaded */
2080 if (CmpIsHiveAlreadyLoaded(KeyHandle, SourceFile, &LoadedHive))
2081 {
2082 /* That's okay then */
2083 ASSERT(LoadedHive);
2085 }
2086
2087 /* Release the registry */
2089 }
2090
2091 /* Close the key handle if we had one */
2093 return Status;
2094 }
2095
2096 /* Lock the registry shared */
2098
2099 /* Lock loading */
2101
2102 /* Lock the hive to this thread */
2103 CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
2104 CmHive->CreatorOwner = KeGetCurrentThread();
2105
2106 /* Set flag */
2108
2109 /* Link the hive */
2110 Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
2111 TargetKey->RootDirectory,
2112 CmHive,
2113 Allocate,
2114 TargetKey->SecurityDescriptor);
2115 if (NT_SUCCESS(Status))
2116 {
2117 /* Add to HiveList key */
2118 CmpAddToHiveFileList(CmHive);
2119
2120 /* Sync the hive if necessary */
2121 if (Allocate)
2122 {
2123 /* Sync it under the flusher lock */
2125 HvSyncHive(&CmHive->Hive);
2126 CmpUnlockHiveFlusher(CmHive);
2127 }
2128
2129 /* Release the hive */
2130 CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING;
2131 CmHive->CreatorOwner = NULL;
2132 }
2133 else
2134 {
2135 DPRINT1("CmpLinkHiveToMaster failed, Status %lx\n", Status);
2136
2137 /* We're touching this hive, set the loading flag */
2138 CmHive->HiveIsLoading = TRUE;
2139
2140 /* Close associated file handles */
2141 CmpCloseHiveFiles(CmHive);
2142
2143 /* Cleanup its resources */
2144 CmpDestroyHive(CmHive);
2145 }
2146
2147 /* Allow loads */
2149
2150 /* Is this first profile load? */
2152 {
2153 /* User is now logged on, set quotas */
2156 }
2157
2158 /* Unlock the registry */
2160
2161 /* Close handle and return */
2163 return Status;
2164}
#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:276
#define CM_CHECK_REGISTRY_PURGE_VOLATILES
Definition: cmlib.h:229
VOID NTAPI CmpSetGlobalQuotaAllowed(VOID)
Definition: cmquota.c:22
BOOLEAN CmpProfileLoaded
Definition: cmsysini.c:33
BOOLEAN CmpWasSetupBoot
Definition: cmsysini.c:32
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID ExReleasePushLock(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1296
FORCEINLINE VOID ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1036
#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:644
NTSTATUS NTAPI CmpDestroyHive(IN PCMHIVE CmHive)
Definition: cminit.c:242
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:317
PKTHREAD CreatorOwner
Definition: cmlib.h:358
BOOLEAN CreateOperation
Definition: cm.h:441
ULONG HiveFlags
Definition: hivedata.h:347
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_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 2079 of file cmsysini.c.

2081{
2082 ULONG Index1, Index2;
2083
2084 /* Sanity check */
2086
2087 /* Get hash indexes */
2088 Index1 = GET_HASH_INDEX(ConvKey1);
2089 Index2 = GET_HASH_INDEX(ConvKey2);
2090
2091 /* See which one is highest */
2092 if (Index1 < Index2)
2093 {
2094 /* Grab them in the proper order */
2097 }
2098 else
2099 {
2100 /* Grab the second one first, then the first */
2102 if (Index1 != Index2) CmpAcquireKcbLockExclusiveByKey(ConvKey1);
2103 }
2104}
FORCEINLINE VOID CmpAcquireKcbLockExclusiveByKey(IN ULONG ConvKey)
Definition: cm_x.h:126
#define GET_HASH_INDEX(ConvKey)
Definition: cm_x.h:24
#define CMP_ASSERT_REGISTRY_LOCK()
Definition: cm_x.h:52

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:261
PVOID NTAPI CmpAllocateDelayItem(VOID)
Definition: cmalloc.c:199
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:366
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 49 of file registry.c.

53{
55 return FrLdrHeapAlloc(Size, Tag);
56}
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 199 of file cmalloc.c.

200{
202 PCM_ALLOC_PAGE AllocPage;
203 ULONG i;
204 PLIST_ENTRY NextEntry;
205 PAGED_CODE();
206
207 /* Lock the allocation buckets */
209
210 /* Look for an item on the free list */
211SearchList:
213 {
214 /* Get the current entry in the list */
216
217 /* Grab the item */
218 Entry = CONTAINING_RECORD(NextEntry, CM_DELAY_ALLOC, ListEntry);
219
220 /* Clear the list */
221 Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL;
222
223 /* Grab the alloc page */
225
226 /* Decrease free entries */
227 ASSERT(AllocPage->FreeCount != 0);
228 AllocPage->FreeCount--;
229
230 /* Release the lock */
232 return Entry;
233 }
234
235 /* Allocate an allocation page */
236 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_CM);
237 if (AllocPage)
238 {
239 /* Set default entries */
240 AllocPage->FreeCount = CM_DELAYS_PER_PAGE;
241
242 /* Loop each entry */
243 for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
244 {
245 /* Get this entry and link it */
246 Entry = (PVOID)((ULONG_PTR)AllocPage +
247 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
248 i * sizeof(CM_DELAY_ALLOC));
250 &Entry->ListEntry);
251
252 /* Clear the KCB pointer */
253 Entry->Kcb = NULL;
254 }
255
256 /* Do the search again */
257 goto SearchList;
258 }
259
260 /* Release the lock */
262 return NULL;
263}
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:125
#define CmpGetAllocPageFromDelayAlloc(a)
Definition: cm_x.h:276
LIST_ENTRY CmpFreeDelayItemsListHead
Definition: cmalloc.c:22
KGUARDED_MUTEX CmpDelayAllocBucketLock
Definition: cmalloc.c:21
#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:348
#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 /* Release the allocation lock */
182 }
183
184 /* Allocate a KCB only */
185 CurrentKcb = CmpAllocate(sizeof(CM_KEY_CONTROL_BLOCK), TRUE, TAG_KCB);
186 if (CurrentKcb)
187 {
188 /* Set it up */
189 CurrentKcb->PrivateAlloc = 0;
190 CurrentKcb->DelayCloseEntry = NULL;
191 }
192
193 /* Return it */
194 return CurrentKcb;
195}
#define CM_KCBS_PER_PAGE
Definition: cm.h:123
struct _CM_KEY_CONTROL_BLOCK CM_KEY_CONTROL_BLOCK
#define CmpGetAllocPageFromKcb(k)
Definition: cm_x.h:270
LIST_ENTRY CmpFreeKCBListHead
Definition: cmalloc.c:19
BOOLEAN CmpAllocInited
Definition: cmalloc.c:17
KGUARDED_MUTEX CmpAllocBucketLock
Definition: cmalloc.c:18
#define TAG_KCB
Definition: cmlib.h:213
ULONG PrivateAlloc
Definition: cm.h:273
LIST_ENTRY FreeListEntry
Definition: cm.h:302
PVOID DelayCloseEntry
Definition: cm.h:305

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().

◆ CmpAssignSecurityDescriptor()

NTSTATUS CmpAssignSecurityDescriptor ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor 
)

Definition at line 251 of file cmse.c.

253{
254 DPRINT("CmpAssignSecurityDescriptor(%p %p)\n",
255 Kcb, SecurityDescriptor);
256 return STATUS_SUCCESS;
257}

Referenced by CmpDoCreateChild(), and CmpSecurityMethod().

◆ CmpBuildAndLockKcbArray()

PULONG NTAPI CmpBuildAndLockKcbArray ( _In_ PCM_HASH_CACHE_STACK  HashCacheStack,
_In_ ULONG  KcbLockFlags,
_In_ PCM_KEY_CONTROL_BLOCK  Kcb,
_Inout_ PULONG  OuterStackArray,
_In_ ULONG  TotalRemainingSubkeys,
_In_ ULONG  MatchRemainSubkeyLevel 
)

Builds an array of KCBs and locks them. Whether these KCBs are locked exclusively or in shared mode by the calling thread, is specified by the KcbLockFlags parameter. The array is sorted.

Parameters
[in]HashCacheStackA pointer to a hash cache stack. This stack parameter stores the convkey hashes of interested KCBs of a key path name that need to be locked.
[in]KcbLockFlagsDefine a lock flag to lock the KCBs. Consult the CmpLockKcbArray documentation for more information.
[in]KcbA pointer to a key control block to be given. This KCB is included in the array for locking, that is, given by the CmpParseKey from the parser object.
[in,out]OuterStackArrayA pointer to an array that lives on the caller's stack. It acts like an auxiliary array used by the function to store the KCB elements for locking. The expected size of the array is up to 32 elements, which is the imposed limit by CMP_HASH_STACK_LIMIT. This limit also corresponds to the maximum depth of subkey levels.
[in]TotalRemainingSubkeysThe number of total remaining subkey levels.
[in]MatchRemainSubkeyLevelThe number of remaining subkey levels that match.
Returns
Returns a pointer to an array of KCBs that have been locked.
Remarks
The caller HAS THE RESPONSIBILITY to unlock the KCBs after the necessary operations are done!

Definition at line 1302 of file cmkcbncb.c.

1309{
1310 ULONG KcbIndex = 1, HashStackIndex, TotalRemaining;
1311 PULONG LockedKcbs = NULL;
1312 PCM_KEY_CONTROL_BLOCK ParentKcb = Kcb->ParentKcb;;
1313
1314 /* These parameters are expected */
1315 ASSERT(HashCacheStack != NULL);
1316 ASSERT(Kcb != NULL);
1317 ASSERT(OuterStackArray != NULL);
1318
1319 /*
1320 * Ensure when we build an array of KCBs to lock, that
1321 * we don't go beyond the boundary the limit allows us
1322 * to. 1 is the current KCB we would want to lock
1323 * alongside with the remaining key levels in the formula.
1324 */
1325 TotalRemaining = (1 + TotalRemainingSubkeys) - MatchRemainSubkeyLevel;
1326 ASSERT(TotalRemaining <= CMP_KCBS_IN_ARRAY_LIMIT);
1327
1328 /* Count the parent if we have one */
1329 if (ParentKcb)
1330 {
1331 /* Ensure we are still below the limit and add the parent to KCBs to lock */
1332 if (TotalRemainingSubkeys == MatchRemainSubkeyLevel)
1333 {
1334 TotalRemaining++;
1335 ASSERT(TotalRemaining <= CMP_KCBS_IN_ARRAY_LIMIT);
1336 OuterStackArray[KcbIndex++] = GET_HASH_INDEX(ParentKcb->ConvKey);
1337 }
1338 }
1339
1340 /* Add the current KCB */
1341 OuterStackArray[KcbIndex++] = GET_HASH_INDEX(Kcb->ConvKey);
1342
1343 /* Loop over the hash stack and grab the hashes for locking (they will be converted to indices) */
1344 for (HashStackIndex = 0;
1345 HashStackIndex < TotalRemainingSubkeys;
1346 HashStackIndex++)
1347 {
1348 OuterStackArray[KcbIndex++] = GET_HASH_INDEX(HashCacheStack[HashStackIndex].ConvKey);
1349 }
1350
1351 /*
1352 * Store how many KCBs we need to lock and sort the array.
1353 * Remove any duplicated indices from the array if any.
1354 */
1355 OuterStackArray[0] = KcbIndex - 1;
1356 CmpSortKcbArray(OuterStackArray);
1357
1358 /* Lock them */
1359 CmpLockKcbArray(OuterStackArray, KcbLockFlags);
1360
1361 /* Give the locked KCBs to caller now */
1362 LockedKcbs = OuterStackArray;
1363 return LockedKcbs;
1364}
#define CMP_KCBS_IN_ARRAY_LIMIT
Definition: cm.h:132
static VOID CmpSortKcbArray(_Inout_ PULONG KcbArray)
Sorts an array of KCB hashes in ascending order and removes any key indices that are duplicates....
Definition: cmkcbncb.c:1211
static VOID CmpLockKcbArray(_In_ PULONG KcbArray, _In_ ULONG KcbLockFlags)
Locks a given number of KCBs.
Definition: cmkcbncb.c:1177
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by CmpBuildHashStackAndLookupCache(), and CmpLookInCache().

◆ 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(), CmpEnumerateOpenSubKeys(), and CmpLookInCache().

◆ 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:42
#define CMP_GET_CACHED_CELL(c)
Definition: cm_x.h:40
uint32_t * PULONG_PTR
Definition: typedefs.h:65

Referenced by CmDeleteValueKey(), CmpCleanUpKcbCacheWithLock(), CmpCompareNewValueDataAgainstKCBCache(), CmpDoOpen(), 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(), CmpCreateLinkNode(), CmpDoCreate(), CmpEnumerateOpenSubKeys(), and CmUnloadKey().

◆ CmpCloseHiveFiles()

VOID NTAPI CmpCloseHiveFiles ( IN PCMHIVE  Hive)

Definition at line 644 of file cminit.c.

645{
646 ULONG i;
647
648 for (i = 0; i < HFILE_TYPE_MAX; i++)
649 {
650 if (Hive->FileHandles[i] != NULL)
651 {
652 ZwClose(Hive->FileHandles[i]);
653 Hive->FileHandles[i] = NULL;
654 }
655 }
656}
#define HFILE_TYPE_MAX
Definition: hivedata.h:37

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 162 of file cmsysini.c.

167{
169 PAGED_CODE();
170
171 /* Don't do anything if we're not the last handle */
172 if (SystemHandleCount > 1) return;
173
174 /* Make sure we're a valid key body */
175 if (KeyBody->Type == CM_KEY_BODY_TYPE)
176 {
177 /* Don't do anything if we don't have a notify block */
178 if (!KeyBody->NotifyBlock) return;
179
180 /* This shouldn't happen yet */
181 ASSERT(FALSE);
182 }
183}
struct _CM_KEY_BODY * PCM_KEY_BODY
#define CM_KEY_BODY_TYPE
Definition: cm.h:64
ULONG Type
Definition: cm.h:233
struct _CM_NOTIFY_BLOCK * NotifyBlock
Definition: cm.h:235
_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 276 of file cmlazy.c.

281{
286 OBJECT_NAME_INFORMATION DummyNameInfo;
287 POBJECT_NAME_INFORMATION FileNameInfo;
288
289 PAGED_CODE();
290
291 if (FileAttributes->RootDirectory)
292 {
293 /*
294 * Validity check: The ObjectName is relative to RootDirectory,
295 * therefore it must not start with a path separator.
296 */
297 if (FileAttributes->ObjectName && FileAttributes->ObjectName->Buffer &&
298 FileAttributes->ObjectName->Length >= sizeof(WCHAR) &&
299 *FileAttributes->ObjectName->Buffer == OBJ_NAME_PATH_SEPARATOR)
300 {
302 }
303
304 /* Determine the right buffer size and allocate */
305 Status = ZwQueryObject(FileAttributes->RootDirectory,
307 &DummyNameInfo,
308 sizeof(DummyNameInfo),
309 &Length);
311 {
312 DPRINT1("CmpCmdHiveOpen(): Root directory handle object name size query failed, Status = 0x%08lx\n", Status);
313 return Status;
314 }
315
316 FileNameInfo = ExAllocatePoolWithTag(PagedPool,
317 Length + sizeof(UNICODE_NULL),
318 TAG_CM);
319 if (FileNameInfo == NULL)
320 {
321 DPRINT1("CmpCmdHiveOpen(): Unable to allocate memory\n");
323 }
324
325 /* Try to get the value */
326 Status = ZwQueryObject(FileAttributes->RootDirectory,
328 FileNameInfo,
329 Length,
330 &Length);
331 if (!NT_SUCCESS(Status))
332 {
333 /* Fail */
334 DPRINT1("CmpCmdHiveOpen(): Root directory handle object name query failed, Status = 0x%08lx\n", Status);
335 ExFreePoolWithTag(FileNameInfo, TAG_CM);
336 return Status;
337 }
338
339 /* Null-terminate and add the length of the terminator */
341 FilePath = FileNameInfo->Name.Buffer;
342 FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
343 Length += sizeof(UNICODE_NULL);
344
345 /* Compute the size of the full path; Length already counts the terminating NULL */
346 Length = Length + sizeof(WCHAR) + FileAttributes->ObjectName->Length;
348 {
349 /* Name size too long, bail out */
350 ExFreePoolWithTag(FileNameInfo, TAG_CM);
352 }
353
354 /* Build the full path */
355 RtlInitEmptyUnicodeString(&FileName, NULL, 0);
357 if (!FileName.Buffer)
358 {
359 /* Fail */
360 DPRINT1("CmpCmdHiveOpen(): Unable to allocate memory\n");
361 ExFreePoolWithTag(FileNameInfo, TAG_CM);
363 }
364 FileName.MaximumLength = Length;
365 RtlCopyUnicodeString(&FileName, &FileNameInfo->Name);
366 ExFreePoolWithTag(FileNameInfo, TAG_CM);
367
368 /*
369 * Append a path terminator if needed (we have already accounted
370 * for a possible extra one when allocating the buffer).
371 */
372 if (/* FileAttributes->ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR && */ // We excluded ObjectName starting with a path separator above.
373 FileName.Length > 0 && FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR)
374 {
375 /* ObjectName does not start with '\' and PathBuffer does not end with '\' */
376 FileName.Buffer[FileName.Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
377 FileName.Length += sizeof(WCHAR);
378 FileName.Buffer[FileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
379 }
380
381 /* Append the object name */
383 if (!NT_SUCCESS(Status))
384 {
385 /* Fail */
386 DPRINT1("CmpCmdHiveOpen(): RtlAppendUnicodeStringToString() failed, Status = 0x%08lx\n", Status);
388 return Status;
389 }
390 }
391 else
392 {
393 FileName = *FileAttributes->ObjectName;
394 }
395
396 /* Open the file in the current security context */
398 0,
399 NewHive,
400 Allocate,
401 CheckFlags);
402 if (((Status == STATUS_ACCESS_DENIED) ||
408 ImpersonationContext)
409 {
410 /* We failed due to an account/security error, impersonate SYSTEM */
411 Status = SeImpersonateClientEx(ImpersonationContext, NULL);
412 if (NT_SUCCESS(Status))
413 {
414 /* Now try again */
416 0,
417 NewHive,
418 Allocate,
419 CheckFlags);
420
421 /* Restore impersonation token */
423 }
424 }
425
426 if (FileAttributes->RootDirectory)
427 {
429 }
430
431 /* Return status of open attempt */
432 return Status;
433}
#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:289
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 233 of file cmlazy.c.

234{
236 PAGED_CODE();
237
238 /* Setup the lazy DPC */
239 KeInitializeDpc(&CmpLazyFlushDpc, CmpLazyFlushDpcRoutine, NULL);
240
241 /* Setup the lazy timer */
243
244 /* Setup the lazy worker */
245 ExInitializeWorkItem(&CmpLazyWorkItem, CmpLazyFlushWorker, NULL);
246
247 /* Setup the forced-lazy DPC and timer */
249 CmpEnableLazyFlushDpcRoutine,
250 NULL);
252
253 /* Enable lazy flushing after 10 minutes */
254 DueTime.QuadPart = Int32x32To64(600, -10 * 1000 * 1000);
256
257 /* Setup flush variables */
259 CmpWasSetupBoot = SetupBoot;
260
261 /* Testing: Force Lazy Flushing */
263
264 /* Setup the system hives list if this is not a Setup boot */
265 if (!SetupBoot)
267
268 /* Now that the system hives are loaded, if we are in PE mode,
269 * all other hives will be loaded with full access */
270 if (CmpMiniNTBoot)
272}
KDPC CmpEnableLazyFlushDpc
Definition: cmlazy.c:20
KTIMER CmpEnableLazyFlushTimer
Definition: cmlazy.c:19
KDPC CmpLazyFlushDpc
Definition: cmlazy.c:17
WORK_QUEUE_ITEM CmpLazyWorkItem
Definition: cmlazy.c:18
BOOLEAN CmpHoldLazyFlush
Definition: cmlazy.c:23
KTIMER CmpLazyFlushTimer
Definition: cmlazy.c:16
VOID NTAPI CmpInitializeHiveList(VOID)
Definition: cmsysini.c:1467
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:88
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:156
#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:290
ULONG ExtFlags
Definition: cm.h:272
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
BOOLEAN Compressed
Definition: cm.h:248
USHORT NameLength
Definition: cm.h:257
WCHAR Name[ANYSIZE_ARRAY]
Definition: cm.h:258
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 = COMPUTE_HASH_CHAR(ConvKey, *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);
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:82
FORCEINLINE VOID CmpReleaseKcbLockByKey(ULONG ConvKey)
Definition: cm_x.h:195
#define COMPUTE_HASH_CHAR(ConvKey, Char)
Definition: cm_x.h:18
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
ULONG Count
Definition: cm.h:211
ULONG ValueList
Definition: cm.h:214
ULONG TotalLevels
Definition: cm.h:276
USHORT KcbMaxValueNameLen
Definition: cm.h:308
ULONG DelayedCloseIndex
Definition: cm.h:275
ULONG KcbMaxValueDataLen
Definition: cm.h:309
CM_KEY_HASH KeyHash
Definition: cm.h:280
ULONG RefCount
Definition: cm.h:269
LARGE_INTEGER KcbLastWriteTime
Definition: cm.h:306
ULONG Signature
Definition: cm.h:268
USHORT KcbMaxNameLen
Definition: cm.h:307
ULONG InDelayClose
Definition: cm.h:317
ULONG SubKeyCount
Definition: cm.h:297
CACHED_CHILD_LIST ValueCache
Definition: cm.h:292

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,
IN PULONG  KcbsLocked,
OUT PVOID Object 
)

Definition at line 830 of file cmparse.c.

840{
842 HCELL_INDEX KeyCell, LinkCell, ChildCell;
843 PCM_KEY_BODY KeyBody;
845 PCM_KEY_NODE KeyNode;
846 PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb;
847
848 /* Link nodes only allowed on the master */
849 if (Hive != &CmiVolatileHive->Hive)
850 {
851 /* Fail */
852 DPRINT1("Invalid link node attempt\n");
854 }
855
856 /* Make sure the KCB is locked and lock the flusher */
857 CMP_ASSERT_KCB_LOCK(ParentKcb);
859 CmpLockHiveFlusherShared((PCMHIVE)Context->ChildHive.KeyHive);
860
861 /* Bail out on read-only KCBs */
862 if (ParentKcb->ExtFlags & CM_KCB_READ_ONLY_KEY)
863 {
865 goto Exit;
866 }
867
868 /* Check if the parent is being deleted */
869 if (ParentKcb->Delete)
870 {
871 /* It is, quit */
872 ASSERT(FALSE);
874 goto Exit;
875 }
876
877 /* Allocate a link node */
878 LinkCell = HvAllocateCell(Hive,
880 CmpNameSize(Hive, &Name),
881 Stable,
882 HCELL_NIL);
883 if (LinkCell == HCELL_NIL)
884 {
885 /* Fail */
887 goto Exit;
888 }
889
890 /* Get the key cell */
891 KeyCell = Context->ChildHive.KeyCell;
892 if (KeyCell != HCELL_NIL)
893 {
894 /* Hive exists! */
895 ChildCell = KeyCell;
896
897 /* Get the node data */
898 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
899 if (!KeyNode)
900 {
901 /* Fail */
902 ASSERT(FALSE);
904 goto Exit;
905 }
906
907 /* Fill out the data */
908 KeyNode->Parent = LinkCell;
909 KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
910 HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
911
912 /* Now open the key cell */
913 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, KeyCell);
914 if (!KeyNode)
915 {
916 /* Fail */
917 ASSERT(FALSE);
919 goto Exit;
920 }
921
922 /* Open the parent */
923 Status = CmpDoOpen(Context->ChildHive.KeyHive,
924 KeyCell,
925 KeyNode,
929 NULL,
931 &Kcb,
932 KcbsLocked,
933 &Name,
934 Object);
935 HvReleaseCell(Context->ChildHive.KeyHive, KeyCell);
936 }
937 else
938 {
939 /* Do the actual create operation */
940 Status = CmpDoCreateChild(Context->ChildHive.KeyHive,
941 Cell,
942 NULL,
944 &Name,
946 Context,
947 ParentKcb,
949 &ChildCell,
950 Object);
951 if (NT_SUCCESS(Status))
952 {
953 /* Setup root pointer */
954 Context->ChildHive.KeyHive->BaseBlock->RootCell = ChildCell;
955 }
956 }
957
958 /* Check if open or create suceeded */
959 if (NT_SUCCESS(Status))
960 {
961 /* Mark the cell dirty */
962 HvMarkCellDirty(Context->ChildHive.KeyHive, ChildCell, FALSE);
963
964 /* Get the key node */
965 KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
966 if (!KeyNode)
967 {
968 /* Fail */
969 ASSERT(FALSE);
971 goto Exit;
972 }
973
974 /* Release it */
975 HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
976
977 /* Set the parent and flags */
978 KeyNode->Parent = LinkCell;
979 KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
980
981 /* Get the link node */
982 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, LinkCell);
983 if (!KeyNode)
984 {
985 /* Fail */
986 ASSERT(FALSE);
988 goto Exit;
989 }
990
991 /* Set it up */
993 KeyNode->Flags = KEY_HIVE_EXIT | KEY_NO_DELETE;
994 KeyNode->Parent = Cell;
995 KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, &Name);
996 if (KeyNode->NameLength < Name.Length) KeyNode->Flags |= KEY_COMP_NAME;
998 KeyNode->LastWriteTime = TimeStamp;
999
1000 /* Clear out the rest */
1001 KeyNode->SubKeyCounts[Stable] = 0;
1002 KeyNode->SubKeyCounts[Volatile] = 0;
1003 KeyNode->SubKeyLists[Stable] = HCELL_NIL;
1004 KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
1005 KeyNode->ValueList.Count = 0;
1006 KeyNode->ValueList.List = HCELL_NIL;
1007 KeyNode->ClassLength = 0;
1008
1009 /* Reference the root node */
1010 KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
1011 KeyNode->ChildHiveReference.KeyCell = ChildCell;
1012 HvReleaseCell(Hive, LinkCell);
1013
1014 /* Get the parent node */
1015 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
1016 if (!KeyNode)
1017 {
1018 /* Fail */
1019 ASSERT(FALSE);
1021 goto Exit;
1022 }