ReactOS 0.4.15-dev-7958-gcd0bb1a
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 }
1023
1024 /* Now add the subkey */
1025 if (!CmpAddSubKey(Hive, Cell, LinkCell))
1026 {
1027 /* Failure! We don't handle this yet! */
1028 ASSERT(FALSE);
1029 }
1030
1031 /* Get the key body */
1032 KeyBody = (PCM_KEY_BODY)*Object;
1033
1034 /* Clean up information on this subkey */
1035 CmpCleanUpSubKeyInfo(KeyBody->KeyControlBlock->ParentKcb);
1036
1037 /* Sanity checks */
1038 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
1039 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
1040 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
1041
1042 /* Update the timestamp */
1044 KeyNode->LastWriteTime = TimeStamp;
1045 KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
1046
1047 /* Check if we need to update name maximum */
1048 if (KeyNode->MaxNameLen < Name.Length)
1049 {
1050 /* Do it */
1051 KeyNode->MaxNameLen = Name.Length;
1052 KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name.Length;
1053 }
1054
1055 /* Check if we need to update class length maximum */
1056 if (KeyNode->MaxClassLen < Context->Class.Length)
1057 {
1058 /* Update it */
1059 KeyNode->MaxClassLen = Context->Class.Length;
1060 }
1061
1062 /* Release the cell */
1063 HvReleaseCell(Hive, Cell);
1064 }
1065 else
1066 {
1067 /* Release the link cell */
1068 HvReleaseCell(Hive, LinkCell);
1069 }
1070
1071Exit:
1072 /* Release the flusher locks and return status */
1073 CmpUnlockHiveFlusher((PCMHIVE)Context->ChildHive.KeyHive);
1075 return Status;
1076}
#define CMP_CREATE_KCB_KCB_LOCKED
Definition: cm.h:89
#define CM_KCB_READ_ONLY_KEY
Definition: cm.h:59
#define KEY_COMP_NAME
Definition: cmdata.h:35
#define CM_LINK_NODE_SIGNATURE
Definition: cmdata.h:22
BOOLEAN NTAPI CmpAddSubKey(IN PHHIVE Hive, IN HCELL_INDEX Parent, IN HCELL_INDEX Child)
Definition: cmindex.c:1465
USHORT NTAPI CmpCopyName(IN PHHIVE Hive, OUT PWCHAR Destination, IN PCUNICODE_STRING Source)
Definition: cmname.c:21
USHORT NTAPI CmpNameSize(IN PHHIVE Hive, IN PCUNICODE_STRING Name)
Definition: cmname.c:74
NTSTATUS NTAPI CmpDoOpen(IN PHHIVE Hive, IN HCELL_INDEX Cell, IN PCM_KEY_NODE Node, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN PCM_PARSE_CONTEXT Context OPTIONAL, IN ULONG ControlFlags, IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb, IN PULONG KcbsLocked, IN PUNICODE_STRING KeyName, OUT PVOID *Object)
Definition: cmparse.c:601
NTSTATUS NTAPI CmpDoCreateChild(IN PHHIVE Hive, IN HCELL_INDEX ParentCell, IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, IN PACCESS_STATE AccessState, IN PUNICODE_STRING Name, IN KPROCESSOR_MODE AccessMode, IN PCM_PARSE_CONTEXT ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, IN ULONG Flags, OUT PHCELL_INDEX KeyCell, OUT PVOID *Object)
Definition: cmparse.c:204
SECURITY_INTEGER TimeStamp
Definition: sspi.h:78
static void Exit(void)
Definition: sock.c:1330
USHORT Signature
Definition: cmdata.h:92
CM_KEY_REFERENCE ChildHiveReference
Definition: cmdata.h:105
HCELL_INDEX Parent
Definition: cmdata.h:96
HCELL_INDEX SubKeyLists[HTYPE_COUNT]
Definition: cmdata.h:102
ULONG MaxNameLen
Definition: cmdata.h:109
USHORT NameLength
Definition: cmdata.h:114
USHORT ClassLength
Definition: cmdata.h:115
ULONG MaxClassLen
Definition: cmdata.h:110
USHORT Flags
Definition: cmdata.h:93
LARGE_INTEGER LastWriteTime
Definition: cmdata.h:94
PHHIVE KeyHive
Definition: cmdata.h:84
HCELL_INDEX KeyCell
Definition: cmdata.h:83
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:118
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by CmpParseKey().

◆ CmpDeepCopyKey()

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

Definition at line 2644 of file cmapi.c.

2649{
2650 /* Call the internal function */
2651 return CmpDeepCopyKeyInternal(SourceHive,
2652 SrcKeyCell,
2653 DestinationHive,
2654 HCELL_NIL,
2655 StorageType,
2656 DestKeyCell);
2657}
static NTSTATUS CmpDeepCopyKeyInternal(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HCELL_INDEX Parent, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2468

Referenced by CmSaveKey(), and CmSaveMergedKeys().

◆ CmpDelayDerefKeyControlBlock()

VOID NTAPI CmpDelayDerefKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 286 of file cmdelay.c.

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

Referenced by CmpCleanUpKcbCacheWithLock(), CmpCleanUpKcbValueCache(), and CmpDeleteKeyObject().

◆ CmpDeleteKeyObject()

VOID NTAPI CmpDeleteKeyObject ( IN PVOID  Object)

◆ CmpDereferenceKeyControlBlock()

VOID NTAPI CmpDereferenceKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 571 of file cmkcbncb.c.

572{
573 LONG OldRefCount, NewRefCount;
574 ULONG ConvKey;
576 "%s - Dereferencing KCB: %p\n", __FUNCTION__, Kcb);
577
578 /* Get the ref count and update it */
579 OldRefCount = *(PLONG)&Kcb->RefCount;
580 NewRefCount = OldRefCount - 1;
581
582 /* Check if we still have references */
583 if ((NewRefCount & 0xFFFF) > 0)
584 {
585 /* Do the dereference */
586 if (InterlockedCompareExchange((PLONG)&Kcb->RefCount,
587 NewRefCount,
588 OldRefCount) == OldRefCount)
589 {
590 /* We'de done */
591 return;
592 }
593 }
594
595 /* Save the key */
596 ConvKey = Kcb->ConvKey;
597
598 /* Do the dereference inside the lock */
601 CmpReleaseKcbLockByKey(ConvKey);
602}

Referenced by CmpLookInCache(), and CmpParseKey().

◆ CmpDereferenceKeyControlBlockWithLock()

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

Definition at line 606 of file cmkcbncb.c.

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

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

◆ CmpDestroyHive()

NTSTATUS NTAPI CmpDestroyHive ( IN PCMHIVE  CmHive)

Definition at line 242 of file cminit.c.

243{
244 /* Remove the hive from the list */
246 RemoveEntryList(&CmHive->HiveList);
248
249 /* Destroy the security descriptor cache */
251
252 /* Destroy the view list */
254
255 /* Delete the flusher lock */
256 ExDeleteResourceLite(CmHive->FlusherLock);
257 ExFreePoolWithTag(CmHive->FlusherLock, TAG_CMHIVE);
258
259 /* Delete the view lock */
260 ExFreePoolWithTag(CmHive->ViewLock, TAG_CMHIVE);
261
262 /* Free the hive storage */
263 HvFree(&CmHive->Hive);
264
265 /* Free the hive */
266 CmpFree(CmHive, TAG_CM);
267
268 return STATUS_SUCCESS;
269}
#define TAG_CMHIVE
Definition: cmlib.h:214
VOID CMAPI HvFree(PHHIVE RegistryHive)
VOID NTAPI CmpDestroyHiveViewList(IN PCMHIVE Hive)
Definition: cmmapvw.c:35
VOID NTAPI CmpDestroySecurityCache(IN PCMHIVE Hive)
Definition: cmsecach.c:41
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647

Referenced by CmLoadKey(), CmpHasAlternateHiveDiverged(), CmSaveKey(), and CmSaveMergedKeys().

◆ CmpDestroyHiveViewList()

VOID NTAPI CmpDestroyHiveViewList ( IN PCMHIVE  Hive)

Definition at line 35 of file cmmapvw.c.

36{
37 PCM_VIEW_OF_FILE CmView;
38 PLIST_ENTRY EntryList;
39
40 /* Do NOT destroy the views of read-only hives */
41 ASSERT(Hive->Hive.ReadOnly == FALSE);
42
43 /* Free all the views inside the Pinned View List */
44 while (!IsListEmpty(&Hive->PinViewListHead))
45 {
46 EntryList = RemoveHeadList(&Hive->PinViewListHead);
47
48 CmView = CONTAINING_RECORD(EntryList, CM_VIEW_OF_FILE, PinViewList);
49
50 /* FIXME: Unmap the view if it is mapped */
51
52 ExFreePool(CmView);
53
54 Hive->PinnedViews--;
55 }
56
57 /* The Pinned View List should be empty */
58 ASSERT(IsListEmpty(&Hive->PinViewListHead) == TRUE);
59 ASSERT(Hive->PinnedViews == 0);
60
61 /* Now, free all the views inside the LRU View List */
62 while (!IsListEmpty(&Hive->LRUViewListHead))
63 {
64 EntryList = RemoveHeadList(&Hive->LRUViewListHead);
65
66 CmView = CONTAINING_RECORD(EntryList, CM_VIEW_OF_FILE, LRUViewList);
67
68 /* FIXME: Unmap the view if it is mapped */
69
70 ExFreePool(CmView);
71
72 Hive->MappedViews--;
73 }
74
75 /* The LRU View List should be empty */
76 ASSERT(IsListEmpty(&Hive->LRUViewListHead) == TRUE);
77 ASSERT(Hive->MappedViews == 0);
78}
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by CmpDestroyHive(), and CmUnloadKey().

◆ CmpDestroySecurityCache()

VOID NTAPI CmpDestroySecurityCache ( IN PCMHIVE  Hive)

Definition at line 41 of file cmsecach.c.

42{
43 /* FIXME: clean Hive->SecurityHash and/or Hive->SecurityCache */
44
45 /* Reset data */
46 Hive->SecurityCount = 0;
47 Hive->SecurityCacheSize = 0;
48 Hive->SecurityHitHint = -1;
49 Hive->SecurityCache = NULL;
50}

Referenced by CmpDestroyHive(), and CmUnloadKey().

◆ CmpDoCreate()

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 
)

Definition at line 404 of file cmparse.c.

412{
414 PCELL_DATA CellData;
415 HCELL_INDEX KeyCell;
416 ULONG ParentType;
417 PCM_KEY_BODY KeyBody;
420 PCM_KEY_NODE KeyNode;
421
422 /* Make sure the KCB is locked and lock the flusher */
423 CMP_ASSERT_KCB_LOCK(ParentKcb);
425
426 /* Bail out on read-only KCBs */
427 if (ParentKcb->ExtFlags & CM_KCB_READ_ONLY_KEY)
428 {
430 goto Exit;
431 }
432
433 /* Check if the parent is being deleted */
434 if (ParentKcb->Delete)
435 {
436 /* It has, quit */
437 ASSERT(FALSE);
439 goto Exit;
440 }
441
442 /* Get the parent node */
443 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
444 if (!KeyNode)
445 {
446 /* Fail */
447 ASSERT(FALSE);
449 goto Exit;
450 }
451
452 /* Make sure nobody added us yet */
453 if (CmpFindSubKeyByName(Hive, KeyNode, Name) != HCELL_NIL)
454 {
455 /* Fail */
456 ASSERT(FALSE);
458 goto Exit;
459 }
460
461 /* Sanity check */
462 ASSERT(Cell == ParentKcb->KeyCell);
463
464 /* Get the parent type */
465 ParentType = HvGetCellType(Cell);
466 if ((ParentType == Volatile) &&
467 !(ParseContext->CreateOptions & REG_OPTION_VOLATILE))
468 {
469 /* Children of volatile parents must also be volatile */
470 //ASSERT(FALSE);
472 goto Exit;
473 }
474
475 /* Don't allow children under symlinks */
476 if (ParentKcb->Flags & KEY_SYM_LINK)
477 {
478 /* Fail */
479 ASSERT(FALSE);
481 goto Exit;
482 }
483
484 /* Make the cell dirty for now */
485 HvMarkCellDirty(Hive, Cell, FALSE);
486
487 /* Do the actual create operation */
489 Cell,
492 Name,
494 ParseContext,
495 ParentKcb,
496 0,
497 &KeyCell,
498 Object);
499 if (NT_SUCCESS(Status))
500 {
501 /* Get the key body */
502 KeyBody = (PCM_KEY_BODY)(*Object);
503
504 /* Now add the subkey */
505 if (!CmpAddSubKey(Hive, Cell, KeyCell))
506 {
507 /* Free the created child */
508 CmpFreeKeyByCell(Hive, KeyCell, FALSE);
509
510 /* Purge out this KCB */
511 KeyBody->KeyControlBlock->Delete = TRUE;
513
514 /* And cleanup the key body object */
517 goto Exit;
518 }
519
520 /* Get the key node */
521 KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
522 if (!KeyNode)
523 {
524 /* Fail, this shouldn't happen */
525 CmpFreeKeyByCell(Hive, KeyCell, TRUE); // Subkey linked above
526
527 /* Purge out this KCB */
528 KeyBody->KeyControlBlock->Delete = TRUE;
530
531 /* And cleanup the key body object */
534 goto Exit;
535 }
536
537 /* Clean up information on this subkey */
538 CmpCleanUpSubKeyInfo(KeyBody->KeyControlBlock->ParentKcb);
539
540 /* Sanity checks */
541 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
542 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
543 ASSERT(KeyBody->KeyControlBlock->ParentKcb == ParentKcb);
544 ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen == KeyNode->MaxNameLen);
545
546 /* Update the timestamp */
548 KeyNode->LastWriteTime = TimeStamp;
549 KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
550
551 /* Check if we need to update name maximum */
552 if (KeyNode->MaxNameLen < Name->Length)
553 {
554 /* Do it */
555 KeyNode->MaxNameLen = Name->Length;
556 KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name->Length;
557 }
558
559 /* Check if we need to update class length maximum */
560 if (KeyNode->MaxClassLen < ParseContext->Class.Length)
561 {
562 /* Update it */
563 KeyNode->MaxClassLen = ParseContext->Class.Length;
564 }
565
566 /* Check if we're creating a symbolic link */
567 if (ParseContext->CreateOptions & REG_OPTION_CREATE_LINK)
568 {
569 /* Get the cell data */
570 CellData = HvGetCell(Hive, KeyCell);
571 if (!CellData)
572 {
573 /* This shouldn't happen */
574 CmpFreeKeyByCell(Hive, KeyCell, TRUE); // Subkey linked above
575
576 /* Purge out this KCB */
577 KeyBody->KeyControlBlock->Delete = TRUE;
579
580 /* And cleanup the key body object */
583 goto Exit;
584 }
585
586 /* Update the flags */
587 CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
588 KeyBody->KeyControlBlock->Flags = CellData->u.KeyNode.Flags;
589 HvReleaseCell(Hive, KeyCell);
590 }
591 }
592
593Exit:
594 /* Release the flusher lock and return status */
596 return Status;
597}
#define HvGetCellType(Cell)
Definition: hivedata.h:120
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1063
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_CHILD_MUST_BE_VOLATILE
Definition: ntstatus.h:618
VOID NTAPI ObDereferenceObjectDeferDelete(IN PVOID Object)
Definition: obref.c:358
CM_KEY_NODE KeyNode
Definition: cmdata.h:200
union _CELL_DATA::@4303 u

Referenced by CmpParseKey().

◆ CmpDoFlushAll()

BOOLEAN NTAPI CmpDoFlushAll ( IN BOOLEAN  ForceFlush)

Definition at line 81 of file cmapi.c.

82{
83 PLIST_ENTRY NextEntry;
84 PCMHIVE Hive;
87
88 /* Make sure that the registry isn't read-only now */
89 if (CmpNoWrite) return TRUE;
90
91 /* Otherwise, acquire the hive list lock and disable force flush */
94
95 /* Loop the hive list */
96 NextEntry = CmpHiveListHead.Flink;
97 while (NextEntry != &CmpHiveListHead)
98 {
99 /* Get the hive */
100 Hive = CONTAINING_RECORD(NextEntry, CMHIVE, HiveList);
101 if (!(Hive->Hive.HiveFlags & HIVE_NOLAZYFLUSH))
102 {
103 /* Acquire the flusher lock */
105
106 /* Check for illegal state */
107 if (ForceFlush && Hive->UseCount)
108 {
109 /* Registry needs to be locked down */
111 UNIMPLEMENTED_DBGBREAK("FIXME: Hive is damaged and needs fixup\n");
112 }
113
114 /* Only sync if we are forced to or if it won't cause a hive shrink */
115 if (ForceFlush || !HvHiveWillShrink(&Hive->Hive))
116 {
117 /* Do the sync */
118 Status = HvSyncHive(&Hive->Hive);
119
120 /* If something failed - set the flag and continue looping */
121 if (!NT_SUCCESS(Status))
122 Result = FALSE;
123 }
124 else
125 {
126 /* We won't flush if the hive might shrink */
127 Result = FALSE;
129 }
130
131 /* Release the flusher lock */
133 }
134
135 /* Try the next entry */
136 NextEntry = NextEntry->Flink;
137 }
138
139 /* Release lock and return */
141 return Result;
142}
#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK()
Definition: cm_x.h:67
BOOLEAN CmpForceForceFlush
Definition: cmlazy.c:22
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
FORCEINLINE VOID ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1105
ULONG UseCount
Definition: cmlib.h:337

Referenced by CmFlushKey(), CmpUnlockRegistry(), and CmShutdownSystem().

◆ CmpEnumerateOpenSubKeys()

ULONG NTAPI CmpEnumerateOpenSubKeys ( _In_ PCM_KEY_CONTROL_BLOCK  RootKcb,
_In_ BOOLEAN  LockHeldExclusively,
_In_ BOOLEAN  RemoveEmptyCacheEntries,
_In_ BOOLEAN  DereferenceOpenedEntries 
)

Definition at line 2341 of file cmapi.c.

2346{
2348 PCM_KEY_CONTROL_BLOCK CachedKcb;
2349 PCM_KEY_CONTROL_BLOCK ParentKcb;
2350 ULONG ParentKeyCount;
2351 ULONG i, j;
2352 ULONG SubKeys = 0;
2353
2354 DPRINT("CmpEnumerateOpenSubKeys() called\n");
2355
2356 /* The root key is the only referenced key. There are no referenced sub keys. */
2357 if (RootKcb->RefCount == 1)
2358 {
2359 DPRINT("Open sub keys: 0\n");
2360 return 0;
2361 }
2362
2363 /* Enumerate all hash lists */
2364 for (i = 0; i < CmpHashTableSize; i++)
2365 {
2366 /* Get the first cache entry */
2368
2369 /* Enumerate all cache entries */
2370 while (Entry)
2371 {
2372 /* Get the KCB of the current cache entry */
2374
2375 /* Check keys only that are subkeys to our root key */
2376 if (CachedKcb->TotalLevels > RootKcb->TotalLevels)
2377 {
2378 /* Calculate the number of parent keys to the root key */
2379 ParentKeyCount = CachedKcb->TotalLevels - RootKcb->TotalLevels;
2380
2381 /* Find a parent key that could be the root key */
2382 ParentKcb = CachedKcb;
2383 for (j = 0; j < ParentKeyCount; j++)
2384 {
2385 ParentKcb = ParentKcb->ParentKcb;
2386 }
2387
2388 /* Check whether the parent is the root key */
2389 if (ParentKcb == RootKcb)
2390 {
2391 DPRINT("Found a sub key, RefCount = %u\n", CachedKcb->RefCount);
2392
2393 if (CachedKcb->RefCount > 0)
2394 {
2395 DPRINT("Found a sub key pointing to '%.*s', RefCount = %u\n",
2396 CachedKcb->NameBlock->NameLength, CachedKcb->NameBlock->Name,
2397 CachedKcb->RefCount);
2398
2399 /* If we dereference opened KCBs, don't touch read-only keys */
2400 if (DereferenceOpenedEntries &&
2401 !(CachedKcb->ExtFlags & CM_KCB_READ_ONLY_KEY))
2402 {
2403 /* Registry needs to be locked down */
2405
2406 /* Flush any notifications */
2407 CmpFlushNotifiesOnKeyBodyList(CachedKcb, TRUE); // Lock is already held
2408
2409 /* Clean up information we have on the subkey */
2410 CmpCleanUpSubKeyInfo(CachedKcb->ParentKcb);
2411
2412 /* Get and cache the next cache entry */
2413 // Entry = Entry->NextHash;
2414 Entry = CachedKcb->NextHash;
2415
2416 /* Set the KCB in delete mode and remove it */
2417 CachedKcb->Delete = TRUE;
2418 CmpRemoveKeyControlBlock(CachedKcb);
2419
2420 /* Clear the cell */
2421 CachedKcb->KeyCell = HCELL_NIL;
2422
2423 /* Restart with the next cache entry */
2424 continue;
2425 }
2426 /* Else, the key cannot be dereferenced, and we count it as in use */
2427
2428 /* Count the current hash entry if it is in use */
2429 SubKeys++;
2430 }
2431 else if ((CachedKcb->RefCount == 0) && RemoveEmptyCacheEntries)
2432 {
2433 /* Lock the cached KCB of subkey before removing it from cache entries */
2434 if (!LockHeldExclusively)
2435 CmpAcquireKcbLockExclusive(CachedKcb);
2436
2437 /* Remove the current key from the delayed close list */
2438 CmpRemoveFromDelayedClose(CachedKcb);
2439
2440 /* Remove the current cache entry */
2441 // Lock is either held by ourselves or registry is locked exclusively
2442 CmpCleanUpKcbCacheWithLock(CachedKcb, LockHeldExclusively);
2443
2444 /* Unlock the cached KCB if it was done by ourselves */
2445 if (!LockHeldExclusively)
2446 CmpReleaseKcbLock(CachedKcb);
2447
2448 /* Restart, because the hash list has changed */
2450 continue;
2451 }
2452 }
2453 }
2454
2455 /* Get the next cache entry */
2456 Entry = Entry->NextHash;
2457 }
2458 }
2459
2460 if (SubKeys > 0)
2461 DPRINT1("Open sub keys: %u\n", SubKeys);
2462
2463 return SubKeys;
2464}
VOID NTAPI CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmdelay.c:425
PCM_KEY_HASH_TABLE_ENTRY CmpCacheTable
Definition: cmkcbncb.c:18
ULONG CmpHashTableSize
Definition: cmkcbncb.c:17
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 GLint GLint j
Definition: glfuncs.h:250
PCM_KEY_HASH NextHash
Definition: cm.h:284
PCM_KEY_HASH Entry
Definition: cm.h:162

Referenced by CmUnloadKey(), and NtQueryOpenSubKeys().

◆ CmpFileFlush()

BOOLEAN NTAPI CmpFileFlush ( IN PHHIVE  RegistryHive,
IN ULONG  FileType,
IN OUT PLARGE_INTEGER  FileOffset,
IN ULONG  Length 
)

Definition at line 192 of file cmwraprs.c.

196{
197 PCMHIVE CmHive = (PCMHIVE)RegistryHive;
198 HANDLE HiveHandle = CmHive->FileHandles[FileType];
201
202 /* Just return success if no file is associated with this hive */
203 if (HiveHandle == NULL)
204 return TRUE;
205
206 /* Don't do anything if we're not supposed to */
207 if (CmpNoWrite)
208 return TRUE;
209
211
212 /* This operation is always synchronous */
215
216 return NT_SUCCESS(Status) ? TRUE : FALSE;
217}
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define STATUS_PENDING
Definition: ntstatus.h:82
HANDLE FileHandles[HFILE_TYPE_MAX]
Definition: cmlib.h:318
_In_ WDFDEVICE _In_ WDF_SPECIAL_FILE_TYPE FileType
Definition: wdfdevice.h:2741
NTSYSAPI NTSTATUS NTAPI ZwFlushBuffersFile(_In_ HANDLE FileHandle, _Out_ PIO_STATUS_BLOCK IoStatusBlock)

Referenced by CmpInitializeHive().

◆ CmpFileRead()

BOOLEAN NTAPI CmpFileRead ( IN PHHIVE  RegistryHive,
IN ULONG  FileType,
IN OUT PULONG  FileOffset,
OUT PVOID  Buffer,
IN SIZE_T  BufferLength 
)

◆ CmpFileSetSize()

BOOLEAN NTAPI CmpFileSetSize ( _In_ PHHIVE  RegistryHive,
_In_ ULONG  FileType,
_In_ ULONG  FileSize,
_In_ ULONG  OldFileSize 
)

Definition at line 132 of file cmwraprs.c.

137{
138 PCMHIVE CmHive = (PCMHIVE)RegistryHive;
139 HANDLE HiveHandle = CmHive->FileHandles[FileType];
140 FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
141 FILE_ALLOCATION_INFORMATION FileAllocationInfo;
143 BOOLEAN HardErrors;
145
146 /* Just return success if no file is associated with this hive */
147 if (HiveHandle == NULL)
148 {
149 DPRINT1("No hive handle associated with the given hive\n");
150 return TRUE;
151 }
152
153 /*
154 * Disable hard errors so that we don't deadlock
155 * when touching with the hive files.
156 */
157 HardErrors = IoSetThreadHardErrorMode(FALSE);
158
159 EndOfFileInfo.EndOfFile.QuadPart = FileSize;
160 Status = ZwSetInformationFile(HiveHandle,
162 &EndOfFileInfo,
165 if (!NT_SUCCESS(Status))
166 {
167 DPRINT1("ZwSetInformationFile failed to set new size of end of file (Status 0x%lx)\n", Status);
168 IoSetThreadHardErrorMode(HardErrors);
169 return FALSE;
170 }
171
172 FileAllocationInfo.AllocationSize.QuadPart = FileSize;
173 Status = ZwSetInformationFile(HiveHandle,
175 &FileAllocationInfo,
178 if (!NT_SUCCESS(Status))
179 {
180 DPRINT1("ZwSetInformationFile failed to set new of allocation file (Status 0x%lx)\n", Status);
181 IoSetThreadHardErrorMode(HardErrors);
182 return FALSE;
183 }
184
185 /* Reset the hard errors back */
186 IoSetThreadHardErrorMode(HardErrors);
187 return TRUE;
188}
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileAllocationInformation
Definition: from_kernel.h:80
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726
LARGE_INTEGER AllocationSize
Definition: winternl.h:688
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CmpInitializeHive().

◆ CmpFileWrite()

BOOLEAN NTAPI CmpFileWrite ( IN PHHIVE  RegistryHive,
IN ULONG  FileType,
IN OUT PULONG  FileOffset,
IN PVOID  Buffer,
IN SIZE_T  BufferLength 
)

◆ CmpFindValueByNameFromCache()

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 at line 194 of file cmvalche.c.

201{
202 PHHIVE Hive;
204 LONG Result;
205 UNICODE_STRING SearchName;
206 PCELL_DATA CellData;
208 PCM_KEY_VALUE KeyValue;
209 BOOLEAN IndexIsCached;
210 ULONG i = 0;
211 HCELL_INDEX Cell = HCELL_NIL;
212
213 /* Set defaults */
214 *CellToRelease = HCELL_NIL;
215 *Value = NULL;
216
217 /* Get the hive and child list */
218 Hive = Kcb->KeyHive;
219 ChildList = &Kcb->ValueCache;
220
221 /* Check if the child list has any entries */
222 if (ChildList->Count != 0)
223 {
224 /* Get the value list associated to this child list */
225 SearchResult = CmpGetValueListFromCache(Kcb,
226 &CellData,
227 &IndexIsCached,
228 &Cell);
229 if (SearchResult != SearchSuccess)
230 {
231 /* We either failed or need the exclusive lock */
232 ASSERT((SearchResult == SearchFail) || !CmpIsKcbLockedExclusive(Kcb));
233 ASSERT(Cell == HCELL_NIL);
234 return SearchResult;
235 }
236
237 /* The index shouldn't be cached right now */
238 if (IndexIsCached) ASSERT_VALUE_CACHE();
239
240 /* Loop every value */
241 while (TRUE)
242 {
243 /* Check if there's any cell to release */
244 if (*CellToRelease != HCELL_NIL)
245 {
246 /* Release it now */
247 HvReleaseCell(Hive, *CellToRelease);
248 *CellToRelease = HCELL_NIL;
249 }
250
251 /* Get the key value for this index */
252 SearchResult = CmpGetValueKeyFromCache(Kcb,
253 CellData,
254 i,
255 CachedValue,
256 Value,
257 IndexIsCached,
258 ValueIsCached,
259 CellToRelease);
260 if (SearchResult != SearchSuccess)
261 {
262 /* We either failed or need the exclusive lock */
263 ASSERT((SearchResult == SearchFail) || !CmpIsKcbLockedExclusive(Kcb));
264 ASSERT(Cell == HCELL_NIL);
265 return SearchResult;
266 }
267
268 /* Check if the both the index and the value are cached */
269 if (IndexIsCached && *ValueIsCached)
270 {
271 /* We don't expect this yet */
273 Result = -1;
274 }
275 else
276 {
277 /* No cache, so try to compare the name. Is it compressed? */
278 KeyValue = *Value;
279 if (KeyValue->Flags & VALUE_COMP_NAME)
280 {
281 /* It is, do a compressed name comparison */
283 KeyValue->Name,
284 KeyValue->NameLength);
285 }
286 else
287 {
288 /* It's not compressed, so do a standard comparison */
289 SearchName.Length = KeyValue->NameLength;
290 SearchName.MaximumLength = SearchName.Length;
291 SearchName.Buffer = KeyValue->Name;
292 Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
293 }
294 }
295
296 /* Check if we found the value data */
297 if (!Result)
298 {
299 /* We have, return the index of the value and success */
300 *Index = i;
301 SearchResult = SearchSuccess;
302 goto Quickie;
303 }
304
305 /* We didn't find it, try the next entry */
306 if (++i == ChildList->Count)
307 {
308 /* The entire list was parsed, fail */
309 *Value = NULL;
310 SearchResult = SearchFail;
311 goto Quickie;
312 }
313 }
314 }
315
316 /* We should only get here if the child list is empty */
317 ASSERT(ChildList->Count == 0);
318
319Quickie:
320 /* Release the value list cell if required, and return search result */
321 if (Cell != HCELL_NIL) HvReleaseCell(Hive, Cell);
322 return SearchResult;
323}
#define VALUE_COMP_NAME
Definition: cmdata.h:44
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
#define ASSERT_VALUE_CACHE()
Definition: cmvalche.c:37
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
USHORT NameLength
Definition: cmdata.h:125
USHORT Flags
Definition: cmdata.h:129
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by CmpCompareNewValueDataAgainstKCBCache(), and CmQueryValueKey().

◆ CmpFlushNotifiesOnKeyBodyList()

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

Definition at line 1368 of file cmkcbncb.c.

1370{
1371 PLIST_ENTRY NextEntry, ListHead;
1372 PCM_KEY_BODY KeyBody;
1373
1374 /* Sanity check */
1376 while (TRUE)
1377 {
1378 /* Is the list empty? */
1379 ListHead = &Kcb->KeyBodyListHead;
1380 if (!IsListEmpty(ListHead))
1381 {
1382 /* Loop the list */
1383 NextEntry = ListHead->Flink;
1384 while (NextEntry != ListHead)
1385 {
1386 /* Get the key body */
1387 KeyBody = CONTAINING_RECORD(NextEntry, CM_KEY_BODY, KeyBodyList);
1388 ASSERT(KeyBody->Type == CM_KEY_BODY_TYPE);
1389
1390 /* Check for notifications */
1391 if (KeyBody->NotifyBlock)
1392 {
1393 /* Is the lock held? */
1394 if (LockHeld)
1395 {
1396 /* Flush it */
1397 CmpFlushNotify(KeyBody, LockHeld);
1398 ASSERT(KeyBody->NotifyBlock == NULL);
1399 continue;
1400 }
1401
1402 /* Lock isn't held, so we need to take a reference */
1403 if (ObReferenceObjectSafe(KeyBody))
1404 {
1405 /* Now we can flush */
1406 CmpFlushNotify(KeyBody, LockHeld);
1407 ASSERT(KeyBody->NotifyBlock == NULL);
1408
1409 /* Release the reference we took */
1411 continue;
1412 }
1413 }
1414
1415 /* Try the next entry */
1416 NextEntry = NextEntry->Flink;
1417 }
1418 }
1419
1420 /* List has been parsed, exit */
1421 break;
1422 }
1423}
VOID NTAPI CmpFlushNotify(IN PCM_KEY_BODY KeyBody, IN BOOLEAN LockHeld)
Definition: cmnotify.c:30
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22

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

◆ CmpFlushNotify()

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

Definition at line 30 of file cmnotify.c.

32{
33 /* FIXME: TODO */
34 return;
35}

Referenced by CmpFlushNotifiesOnKeyBodyList().

◆ CmpFree()

VOID NTAPI CmpFree ( IN PVOID  Ptr,
IN ULONG  Quota 
)

Definition at line 60 of file registry.c.

63{
66}
FORCEINLINE VOID FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag)
Definition: mm.h:181
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898

◆ CmpFreeDelayItem()

VOID NTAPI CmpFreeDelayItem ( PVOID  Entry)

Definition at line 267 of file cmalloc.c.

268{
270 PCM_ALLOC_PAGE AllocPage;
271 ULONG i;
272 PAGED_CODE();
273
274 /* Lock the table */
276
277 /* Add the entry at the end */
279
280 /* Get the alloc page */
282 ASSERT(AllocPage->FreeCount != CM_DELAYS_PER_PAGE);
283
284 /* Increase the number of free items */
285 if (++AllocPage->FreeCount == CM_DELAYS_PER_PAGE)
286 {
287 /* Page is totally free now, loop each entry */
288 for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
289 {
290 /* Get the entry and unlink it */
291 AllocEntry = (PVOID)((ULONG_PTR)AllocPage +
292 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
293 i * sizeof(CM_DELAY_ALLOC));
294 RemoveEntryList(&AllocEntry->ListEntry);
295 }
296
297 /* Now free the page */
298 CmpFree(AllocPage, TAG_CM);
299 }
300
301 /* Release the lock */
303}
struct _CM_DELAY_ALLOC * PCM_DELAY_ALLOC
LIST_ENTRY ListEntry
Definition: cm.h:358

Referenced by _Function_class_(), and CmpRemoveFromDelayedClose().

◆ CmpFreeKeyControlBlock()

VOID NTAPI CmpFreeKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 53 of file cmalloc.c.

54{
55 ULONG i;
56 PCM_ALLOC_PAGE AllocPage;
57 PAGED_CODE();
58
59 /* Sanity checks */
60 ASSERT(IsListEmpty(&Kcb->KeyBodyListHead) == TRUE);
61 for (i = 0; i < 4; i++) ASSERT(Kcb->KeyBodyArray[i] == NULL);
62
63 /* Check if it wasn't privately allocated */
64 if (!Kcb->PrivateAlloc)
65 {
66 /* Free it from the pool */
67 CmpFree(Kcb, TAG_KCB);
68 return;
69 }
70
71 /* Acquire the private allocation lock */
73
74 /* Sanity check on lock ownership */
75 CMP_ASSERT_HASH_ENTRY_LOCK(Kcb->ConvKey);
76
77 /* Add us to the free list */
78 InsertTailList(&CmpFreeKCBListHead, &Kcb->FreeListEntry);
79
80 /* Get the allocation page */
81 AllocPage = CmpGetAllocPageFromKcb(Kcb);
82
83 /* Sanity check */
84 ASSERT(AllocPage->FreeCount != CM_KCBS_PER_PAGE);
85
86 /* Increase free count */
87 if (++AllocPage->FreeCount == CM_KCBS_PER_PAGE)
88 {
89 /* Loop all the entries */
90 for (i = 0; i < CM_KCBS_PER_PAGE; i++)
91 {
92 /* Get the KCB */
93 Kcb = (PVOID)((ULONG_PTR)AllocPage +
94 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
95 i * sizeof(CM_KEY_CONTROL_BLOCK));
96
97 /* Remove the entry */
98 RemoveEntryList(&Kcb->FreeListEntry);
99 }
100
101 /* Free the page */
102 CmpFree(AllocPage, TAG_KCB);
103 }
104
105 /* Release the lock */
107}
#define CMP_ASSERT_HASH_ENTRY_LOCK(k)
Definition: cm_x.h:251

Referenced by CmpCleanUpKcbCacheWithLock(), and CmpCreateKeyControlBlock().

◆ CmpGetHiveName()

BOOLEAN NTAPI CmpGetHiveName ( IN PCMHIVE  Hive,
OUT PUNICODE_STRING  HiveName 
)

Definition at line 24 of file cmhvlist.c.

26{
27 HCELL_INDEX RootCell, LinkCell;
28 PCELL_DATA RootData, LinkData, ParentData;
29 ULONG ParentNameSize, LinkNameSize;
30 SIZE_T NameSize;
31 PWCHAR p;
32 UNICODE_STRING RegistryName = RTL_CONSTANT_STRING(L"\\REGISTRY\\");
33
34 /* Get the root cell of this hive */
35 RootCell = Hive->Hive.BaseBlock->RootCell;
36 RootData = HvGetCell(&Hive->Hive, RootCell);
37 if (!RootData) return FALSE;
38
39 /* Get the cell index at which this hive is linked to, and its parent */
40 LinkCell = RootData->u.KeyNode.Parent;
41 HvReleaseCell(&Hive->Hive, RootCell);
42
43 /* Sanity check */
44 ASSERT((&CmiVolatileHive->Hive)->ReleaseCellRoutine == NULL);
45
46 /* Get the cell data for link and parent */
47 LinkData = HvGetCell(&CmiVolatileHive->Hive, LinkCell);
48 if (!LinkData) return FALSE;
49 ParentData = HvGetCell(&CmiVolatileHive->Hive, LinkData->u.KeyNode.Parent);
50 if (!ParentData) return FALSE;
51
52 /* Get the size of the parent name */
53 if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
54 {
55 ParentNameSize = CmpCompressedNameSize(ParentData->u.KeyNode.Name,
56 ParentData->u.KeyNode.NameLength);
57 }
58 else
59 {
60 ParentNameSize = ParentData->u.KeyNode.NameLength;
61 }
62
63 /* Get the size of the link name */
64 if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
65 {
66 LinkNameSize = CmpCompressedNameSize(LinkData->u.KeyNode.Name,
67 LinkData->u.KeyNode.NameLength);
68 }
69 else
70 {
71 LinkNameSize = LinkData->u.KeyNode.NameLength;
72 }
73
74 /* No need to account for terminal NULL character since we deal with counted UNICODE strings */
75 NameSize = RegistryName.Length + ParentNameSize + sizeof(WCHAR) + LinkNameSize;
76
77 /* Allocate the memory */
78 HiveName->Buffer = ExAllocatePoolWithTag(PagedPool, NameSize, TAG_CM);
79 if (!HiveName->Buffer)
80 {
81 /* Fail */
82 DPRINT1("CmpGetHiveName: Unable to allocate memory\n");
83 return FALSE;
84 }
85
86 /* Build the string for it */
87 HiveName->Length = HiveName->MaximumLength = (USHORT)NameSize;
88 p = HiveName->Buffer;
89
90 /* Copy the parent name */
91 RtlCopyMemory(p, RegistryName.Buffer, RegistryName.Length);
92 p += RegistryName.Length / sizeof(WCHAR);
93 if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
94 {
96 ParentNameSize,
97 ParentData->u.KeyNode.Name,
98 ParentData->u.KeyNode.NameLength);
99 }
100 else
101 {
102 RtlCopyMemory(p, ParentData->u.KeyNode.Name, ParentNameSize);
103 }
104
105 /* Add a path separator between parent and link */
106 p += ParentNameSize / sizeof(WCHAR);
108 ++p;
109
110 /* Now copy the link name */
111 if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
112 {
114 LinkNameSize,
115 LinkData->u.KeyNode.Name,
116 LinkData->u.KeyNode.NameLength);
117
118 }
119 else
120 {
121 RtlCopyMemory(p, LinkData->u.KeyNode.Name, LinkNameSize);
122 }
123
124 /* All done */
125 return TRUE;
126}
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by CmpAddToHiveFileList(), and CmpRemoveFromHiveFileList().

◆ CmpGetNextName()

BOOLEAN NTAPI CmpGetNextName ( IN OUT PUNICODE_STRING  RemainingName,
OUT PUNICODE_STRING  NextName,
OUT PBOOLEAN  LastName 
)

Definition at line 21 of file cmparse.c.

24{
25 BOOLEAN NameValid = TRUE;
26
27 ASSERT(RemainingName->Length % sizeof(WCHAR) == 0);
28
29 /* Check if there's nothing left in the name */
30 if (!(RemainingName->Buffer) ||
31 (!RemainingName->Length) ||
32 !(*RemainingName->Buffer))
33 {
34 /* Clear the next name and set this as last */
35 *LastName = TRUE;
36 NextName->Buffer = NULL;
37 NextName->Length = 0;
38 return TRUE;
39 }
40
41 /* Check if we have a path separator */
42 while (RemainingName->Length &&
44 {
45 /* Skip it */
46 RemainingName->Buffer++;
47 RemainingName->Length -= sizeof(WCHAR);
48 RemainingName->MaximumLength -= sizeof(WCHAR);
49 }
50
51 /* Start loop at where the current buffer is */
52 NextName->Buffer = RemainingName->Buffer;
53 while (RemainingName->Length &&
55 {
56 /* Move to the next character */
57 RemainingName->Buffer++;
58 RemainingName->Length -= sizeof(WCHAR);
59 RemainingName->MaximumLength -= sizeof(WCHAR);
60 }
61
62 /* See how many chars we parsed and validate the length */
63 NextName->Length = (USHORT)((ULONG_PTR)RemainingName->Buffer -
64 (ULONG_PTR)NextName->Buffer);
65 if (NextName->Length > 512) NameValid = FALSE;
66 NextName->MaximumLength = NextName->Length;
67
68 /* If there's nothing left, we're last */
69 *LastName = !RemainingName->Length;
70 return NameValid;
71}
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define ULONG_PTR
Definition: config.h:101

Referenced by CmpParseKey(), and CmpWalkPath().

◆ CmpGetValueKeyFromCache()

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 at line 96 of file cmvalche.c.

104{
105 PHHIVE Hive;
106 PCM_KEY_VALUE KeyValue;
107 HCELL_INDEX Cell;
108
109 /* Set defaults */
110 *CellToRelease = HCELL_NIL;
111 *Value = NULL;
112 *ValueIsCached = FALSE;
113
114 /* Get the hive */
115 Hive = Kcb->KeyHive;
116
117 /* Check if the index was cached */
118 if (IndexIsCached)
119 {
120 /* Not expected yet! */
122 *ValueIsCached = TRUE;
123 }
124 else
125 {
126 /* Get the cell index and the key value associated to it */
127 Cell = CellData->u.KeyList[Index];
128 KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
129 if (!KeyValue) return SearchFail;
130
131 /* Return the cell and the actual key value */
132 *CellToRelease = Cell;
133 *Value = KeyValue;
134 }
135
136 /* If we got here, then we found the key value */
137 return SearchSuccess;
138}

Referenced by CmEnumerateValueKey(), and CmpFindValueByNameFromCache().

◆ CmpGetValueListFromCache()

VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
OUT PCELL_DATA CellData,
OUT BOOLEAN IndexIsCached,
OUT PHCELL_INDEX  ValueListToRelease 
)

Definition at line 44 of file cmvalche.c.

48{
49 PHHIVE Hive;
51 HCELL_INDEX CellToRelease;
52
53 /* Set defaults */
54 *ValueListToRelease = HCELL_NIL;
55 *IndexIsCached = FALSE;
56
57 /* Get the hive and value cache */
58 Hive = Kcb->KeyHive;
59 ChildList = &Kcb->ValueCache;
60
61 /* Check if the value is cached */
62 if (CmpIsValueCached(ChildList->ValueList))
63 {
64 /* It is: we don't expect this yet! */
66 *IndexIsCached = TRUE;
67 *CellData = NULL;
68 }
69 else
70 {
71 /* Make sure the KCB is locked exclusive */
72 if (!CmpIsKcbLockedExclusive(Kcb) &&
74 {
75 /* We need the exclusive lock */
77 }
78
79 /* Select the value list as our cell, and get the actual list array */
80 CellToRelease = ChildList->ValueList;
81 *CellData = (PCELL_DATA)HvGetCell(Hive, CellToRelease);
82 if (!*CellData) return SearchFail;
83
84 /* FIXME: Here we would cache the value */
85
86 /* Return the cell to be released */
87 *ValueListToRelease = CellToRelease;
88 }
89
90 /* If we got here, then the value list was found */
91 return SearchSuccess;
92}
struct _CELL_DATA * PCELL_DATA
FORCEINLINE BOOLEAN CmpIsValueCached(IN HCELL_INDEX CellIndex)
Definition: cmvalche.c:17

Referenced by CmEnumerateValueKey(), and CmpFindValueByNameFromCache().

◆ CmpHiveRootSecurityDescriptor()

PSECURITY_DESCRIPTOR NTAPI CmpHiveRootSecurityDescriptor ( VOID  )

Definition at line 21 of file cmse.c.

22{
25 PACL Acl, AclCopy;
26 PSID Sid[4];
29 ULONG AceLength, AclLength, SidLength;
30 PACE_HEADER AceHeader;
31 ULONG i;
32 PAGED_CODE();
33
34 /* Phase 1: Allocate SIDs */
35 SidLength = RtlLengthRequiredSid(1);
39 SidLength = RtlLengthRequiredSid(2);
41
42 /* Make sure all SIDs were allocated */
43 if (!Sid[0] || !Sid[1] || !Sid[2] || !Sid[3])
44 {
45 /* Bugcheck */
46 KeBugCheckEx(REGISTRY_ERROR, 11, 1, 0, 0);
47 }
48
49 /* Phase 2: Initialize all SIDs */
54 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 2, 0, 0);
55
56 /* Phase 2: Setup SID Sub Authorities */
62
63 /* Make sure all SIDs are valid */
68
69 /* Phase 3: Calculate ACL Length */
70 AclLength = sizeof(ACL);
71 for (i = 0; i < 4; i++)
72 {
73 /* This is what MSDN says to do */
74 AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
75 AceLength += SeLengthSid(Sid[i]);
76 AclLength += AceLength;
77 }
78
79 /* Phase 3: Allocate the ACL */
81 if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);
82
83 /* Phase 4: Create the ACL */
85 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 4, Status, 0);
86
87 /* Phase 5: Build the ACL */
92 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);
93
94 /* Phase 5: Make the ACEs inheritable */
95 Status = RtlGetAce(Acl, 0, (PVOID*)&AceHeader);
97 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
98 Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
100 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
101 Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
103 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
104 Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
106 AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
107
108 /* Phase 6: Allocate the security descriptor and make space for the ACL */
110 sizeof(SECURITY_DESCRIPTOR) +
111 AclLength,
112 TAG_CMSD);
113 if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);
114
115 /* Phase 6: Make a copy of the ACL */
117 RtlCopyMemory(AclCopy, Acl, AclLength);
118
119 /* Phase 7: Create the security descriptor */
122 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 7, Status, 0);
123
124 /* Phase 8: Set the ACL as a DACL */
126 TRUE,
127 AclCopy,
128 FALSE);
129 if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);
130
131 /* Free the SIDs and original ACL */
132 for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CMSD);
134
135 /* Return the security descriptor */
136 return SecurityDescriptor;
137}
static SID_IDENTIFIER_AUTHORITY NtAuthority
Definition: security.c:40
static SID_IDENTIFIER_AUTHORITY WorldAuthority
Definition: security.c:14
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
struct _ACL ACL
struct _ACL * PACL
Definition: security.c:105
NTSYSAPI PULONG NTAPI RtlSubAuthoritySid(_In_ PSID Sid, _In_ ULONG SubAuthority)
NTSYSAPI ULONG NTAPI RtlLengthRequiredSid(IN ULONG SubAuthorityCount)
Definition: sid.c:54
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI NTSTATUS NTAPI RtlGetAce(PACL Acl, ULONG AceIndex, PVOID *Ace)
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1133
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
UCHAR AceFlags
Definition: ms-dtyp.idl:211
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#define SeLengthSid(Sid)
Definition: sefuncs.h:570
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define SECURITY_WORLD_SID_AUTHORITY
Definition: setypes.h:527
#define SECURITY_WORLD_RID
Definition: setypes.h:541
#define SECURITY_LOCAL_SYSTEM_RID
Definition: setypes.h:574
#define SECURITY_RESTRICTED_CODE_RID
Definition: setypes.h:569
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652

Referenced by CmInitSystem1(), CmpCreateRegistryRoot(), CmpInitializeHiveList(), and CmpInitializeSystemHive().

◆ CmpInitCallback()

VOID NTAPI CmpInitCallback ( VOID  )

Definition at line 38 of file cmhook.c.

39{
40 ULONG i;
41 PAGED_CODE();
42
43 /* Reset counter */
45
46 /* Loop all the callbacks */
47 for (i = 0; i < CMP_MAX_CALLBACKS; i++)
48 {
49 /* Initialize this one */
51 }
52
53 /* ROS: Initialize old-style callbacks for now */
56}
#define CMP_MAX_CALLBACKS
Definition: cm.h:72
EX_CALLBACK CmpCallBackVector[100]
Definition: cmhook.c:18
ULONG CmpCallBackCount
Definition: cmhook.c:17
VOID NTAPI ExInitializeCallBack(IN OUT PEX_CALLBACK Callback)
Definition: callback.c:46
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

Referenced by CmInitSystem1().

◆ CmpInitCmPrivateAlloc()

VOID NTAPI CmpInitCmPrivateAlloc ( VOID  )

Definition at line 29 of file cmalloc.c.

30{
31 /* Make sure we didn't already do this */
32 if (!CmpAllocInited)
33 {
34 /* Setup the lock and list */
38 }
39}

Referenced by CmInitSystem1().

◆ CmpInitCmPrivateDelayAlloc()

VOID NTAPI CmpInitCmPrivateDelayAlloc ( VOID  )

Definition at line 44 of file cmalloc.c.

45{
46 /* Initialize the delay allocation list and lock */
49}

Referenced by CmInitSystem1().

◆ CmpInitDelayDerefKCBEngine()

VOID NTAPI CmpInitDelayDerefKCBEngine ( VOID  )

Definition at line 268 of file cmdelay.c.

269{
270 /* Initialize lock and list */
273
274 /* Setup the work item */
276 CmpDelayDerefKCBWorker,
277 NULL);
278
279 /* Setup the DPC and timer for it */
280 KeInitializeDpc(&CmpDelayDerefKCBDpc, CmpDelayDerefKCBDpcRoutine, NULL);
282}
WORK_QUEUE_ITEM CmpDelayDerefKCBWorkItem
Definition: cmdelay.c:17

Referenced by CmInitSystem1().

◆ CmpInitHiveFromFile()

NTSTATUS NTAPI CmpInitHiveFromFile ( IN PCUNICODE_STRING  HiveName,
IN ULONG  HiveFlags,
OUT PCMHIVE Hive,
IN OUT PBOOLEAN  New,
IN ULONG  CheckFlags 
)

Definition at line 289 of file cmsysini.c.

294{
295 ULONG HiveDisposition, LogDisposition;
299 PCMHIVE NewHive;
300 PAGED_CODE();
301
302 /* Assume failure */
303 *Hive = NULL;
304
305 /* Open or create the hive files */
306 Status = CmpOpenHiveFiles(HiveName,
307 L".LOG",
308 &FileHandle,
309 &LogHandle,
310 &HiveDisposition,
311 &LogDisposition,
312 *New,
313 FALSE,
314 TRUE,
315 NULL);
316 if (!NT_SUCCESS(Status)) return Status;
317
318 /* Check if we have a log handle */
320
321 /* Check if we created or opened the hive */
322 if (HiveDisposition == FILE_CREATED)
323 {
324 /* Do a create operation */
326 *New = TRUE;
327 }
328 else
329 {
330 /* Open it as a file */
332 *New = FALSE;
333 }
334
335 /* Check if the system hives are opened in shared mode */
337 {
338 /* Then force using the primary hive */
340 if (LogHandle)
341 {
342 /* Get rid of the log handle */
344 LogHandle = NULL;
345 }
346 }
347
348 /* Check if we're too late */
350 {
351 /* Fail */
354 return STATUS_TOO_LATE;
355 }
356
357 /* Initialize the hive */
358 Status = CmpInitializeHive(&NewHive,
359 Operation,
360 HiveFlags,
361 FileType,
362 NULL,
364 LogHandle,
365 NULL,
366 NULL,
367 HiveName,
368 CheckFlags);
369 if (!NT_SUCCESS(Status))
370 {
371 /* Fail */
374 return Status;
375 }
376
377 /* Success, return hive */
378 *Hive = NewHive;
379
380 /* Duplicate the hive name */
382 HiveName->Length,
383 TAG_CM);
384 if (NewHive->FileFullPath.Buffer)
385 {
386 /* Copy the string */
388 HiveName->Buffer,
389 HiveName->Length);
390 NewHive->FileFullPath.Length = HiveName->Length;
391 NewHive->FileFullPath.MaximumLength = HiveName->Length;
392 }
393
394 /* Return success */
395 return STATUS_SUCCESS;
396}
BOOLEAN HvShutdownComplete
Definition: cmsysini.c:36
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
FP_OP Operation
Definition: fpcontrol.c:150
#define HINIT_FILE
Definition: hivedata.h:15
#define HFILE_TYPE_LOG
Definition: hivedata.h:34
_In_ UINT _Out_ PNDIS_HANDLE LogHandle
Definition: ndis.h:5382
#define FILE_CREATED
Definition: nt_native.h:770
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)
Definition: cminit.c:273
#define STATUS_TOO_LATE
Definition: ntstatus.h:626
#define New(t)
Definition: rtf.h:1086
UNICODE_STRING FileFullPath
Definition: cmlib.h:333

Referenced by _Function_class_(), and CmpCmdHiveOpen().

◆ CmpInitHiveViewList()

VOID NTAPI CmpInitHiveViewList ( IN PCMHIVE  Hive)

Definition at line 21 of file cmmapvw.c.

22{
23 /* Initialize the list heads */
24 InitializeListHead(&Hive->LRUViewListHead);
25 InitializeListHead(&Hive->PinViewListHead);
26
27 /* Reset data */
28 Hive->MappedViews = 0;
29 Hive->PinnedViews = 0;
30 Hive->UseCount = 0;
31}

Referenced by CmGetSystemControlValues(), and CmpInitializeHive().

◆ CmpInitializeCache()

VOID NTAPI CmpInitializeCache ( VOID  )

Definition at line 26 of file cmkcbncb.c.

27{
28 ULONG Length, i;
29
30 /* Calculate length for the table */
32
33 /* Allocate it */
35 if (!CmpCacheTable)
36 {
37 /* Take the system down */
38 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 1, 0, 0);
39 }
40
41 /* Zero out the table */
43
44 /* Initialize the locks */
45 for (i = 0;i < CmpHashTableSize; i++)
46 {
47 /* Setup the pushlock */
49 }
50
51 /* Calculate length for the name cache */
53
54 /* Now allocate the name cache table */
57 {
58 /* Take the system down */
59 KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 3, 0, 0);
60 }
61
62 /* Zero out the table */
64
65 /* Initialize the locks */
66 for (i = 0;i < CmpHashTableSize; i++)
67 {
68 /* Setup the pushlock */
70 }
71
72 /* Setup the delayed close table */
74}
struct _CM_NAME_HASH_TABLE_ENTRY CM_NAME_HASH_TABLE_ENTRY
struct _CM_KEY_HASH_TABLE_ENTRY CM_KEY_HASH_TABLE_ENTRY
VOID NTAPI CmpInitializeDelayedCloseTable(VOID)
Definition: cmdelay.c:191
PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
Definition: cmkcbncb.c:19
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127

Referenced by CmInitSystem1().

◆ CmpInitializeDelayedCloseTable()

VOID NTAPI CmpInitializeDelayedCloseTable ( VOID  )

Definition at line 191 of file cmdelay.c.

192{
193
194 /* Setup the delayed close lock */
196
197 /* Setup the work item */
198 ExInitializeWorkItem(&CmpDelayCloseWorkItem, CmpDelayCloseWorker, NULL);
199
200 /* Setup the list head */
202
203 /* Setup the DPC and its timer */
204 KeInitializeDpc(&CmpDelayCloseDpc, CmpDelayCloseDpcRoutine, NULL);
206}
WORK_QUEUE_ITEM CmpDelayCloseWorkItem
Definition: cmdelay.c:23

Referenced by CmpInitializeCache().

◆ CmpInitializeHardwareConfiguration()

NTSTATUS NTAPI CmpInitializeHardwareConfiguration ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 329 of file cmconfig.c.

330{
336
337 /* Set the alternative system architecture information */
338#if defined(SARCH_PC98)
339 SharedUserData->AlternativeArchitecture = NEC98x86;
340#endif
341
342 /* Setup the key name */
344 L"\\Registry\\Machine\\Hardware\\DeviceMap");
346 &KeyName,
348 NULL,
349 NULL);
350
351 /* Create the device map key */
355 0,
356 NULL,
357 0,
358 &Disposition);
359 if (!NT_SUCCESS(Status))
360 return Status;
362
363 /* Nobody should've created this key yet! */
365
366 /* Setup the key name */
368 L"\\Registry\\Machine\\Hardware\\Description");
370 &KeyName,
372 NULL,
373 NULL);
374
375 /* Create the description key */
379 0,
380 NULL,
381 0,
382 &Disposition);
383 if (!NT_SUCCESS(Status))
384 return Status;
385
386 /* Nobody should've created this key yet! */
388
389 /* Allocate the configuration data buffer */
392 TAG_CM);
394 {
397 }
398
399 /* Check if we got anything from NTLDR */
400 if (LoaderBlock->ConfigurationRoot)
401 {
402 /* Setup the configuration tree */
403 Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
404 KeyHandle,
406 -1);
407 }
408 else
409 {
410 /* Nothing else to do */
412 }
413
414 /* Free the buffer, close our handle and return status */
417 return Status;
418}
NTSTATUS NTAPI CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE ParentHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber)
Definition: cmconfig.c:205
PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData
Definition: cmdata.c:37
ULONG CmpConfigurationAreaSize
Definition: cmdata.c:36
@ InterfaceTypeUndefined
Definition: hwresource.cpp:136
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define SharedUserData
@ NEC98x86
Definition: ketypes.h:903

Referenced by CmInitSystem1().

◆ CmpInitializeHive()

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 at line 19 of file cminit.c.

31{
32 PCMHIVE Hive;
34 FILE_FS_SIZE_INFORMATION FileSizeInformation;
36 ULONG Cluster;
37
38 /* Assume failure */
39 *CmHive = NULL;
40
41 /*
42 * The following are invalid:
43 * - An external hive that is also internal.
44 * - A log hive that is not a primary hive too.
45 * - A volatile hive that is linked to permanent storage,
46 * unless this hive is a shared system hive.
47 * - An in-memory initialization without hive data.
48 * - A log hive that is not linked to a correct file type.
49 * - An alternate hive that is not linked to a correct file type.
50 * - A lonely alternate hive not backed up with its corresponding primary hive.
51 */
52 if ((External && (Primary || Log)) ||
53 (Log && !Primary) ||
54 (!CmpShareSystemHives && (HiveFlags & HIVE_VOLATILE) &&
55 (Primary || External || Log)) ||
56 ((OperationType == HINIT_MEMORY) && !HiveData) ||
57 (Log && (FileType != HFILE_TYPE_LOG)) ||
58 (Alternate && (FileType != HFILE_TYPE_ALTERNATE)) ||
59 (Alternate && !Primary))
60 {
61 /* Fail the request */
63 }
64
65 /* Check if this is a primary hive */
66 if (Primary)
67 {
68 /* Get the cluster size */
71 &FileSizeInformation,
74 if (!NT_SUCCESS(Status)) return Status;
75
76 /* Make sure it's not larger then the block size */
77 if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE)
78 {
79 /* Fail */
81 }
82
83 /* Otherwise, calculate the cluster */
84 Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE;
85 Cluster = max(1, Cluster);
86 }
87 else
88 {
89 /* Otherwise use cluster 1 */
90 Cluster = 1;
91 }
92
93 /* Allocate the hive */
95 if (!Hive) return STATUS_INSUFFICIENT_RESOURCES;
96
97 /* Setup null fields */
98 Hive->UnloadEvent = NULL;
99 Hive->RootKcb = NULL;
100 Hive->Frozen = FALSE;
101 Hive->UnloadWorkItem = NULL;
102 Hive->GrowOnlyMode = FALSE;
103 Hive->GrowOffset = 0;
104 Hive->CellRemapArray = NULL;
105 Hive->UseCountLog.Next = 0;
106 Hive->LockHiveLog.Next = 0;
107 Hive->FileObject = NULL;
108 Hive->NotifyList.Flink = NULL;
109 Hive->NotifyList.Blink = NULL;
110
111 /* Set the loading flag */
112 Hive->HiveIsLoading = TRUE;
113
114 /* Set the current thread as creator */
116
117 /* Initialize lists */
121
122 /* Allocate the view log */
124 sizeof(KGUARDED_MUTEX),
125 TAG_CMHIVE);
126 if (!Hive->ViewLock)
127 {
128 /* Cleanup allocation and fail */
131 }
132
133 /* Allocate the flush lock */
135 sizeof(ERESOURCE),
136 TAG_CMHIVE);
137 if (!Hive->FlusherLock)
138 {
139 /* Cleanup allocations and fail */
143 }
144
145 /* Setup the handles */
146 Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
147 Hive->FileHandles[HFILE_TYPE_LOG] = Log;
149 Hive->FileHandles[HFILE_TYPE_ALTERNATE] = Alternate;
150
151 /* Initailize the guarded mutex */
153 Hive->ViewLockOwner = NULL;
154
155 /* Initialize the flush lock */
157
158 /* Setup hive locks */
160 Hive->HiveLockOwner = NULL;
162 Hive->WriterLockOwner = NULL;
165
166 /* Clear file names */
167 RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0);
168 RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0);
169
170 /* Initialize the view list */
172
173 /* Initailize the security cache */
175
176 /* Setup flags */
177 Hive->Flags = 0;
178 Hive->FlushCount = 0;
179
180 /* Initialize it */
181 Status = HvInitialize(&Hive->Hive,
182 OperationType,
183 HiveFlags,
184 FileType,
185 HiveData,
187 CmpFree,
192 Cluster,
193 FileName);
194 if (!NT_SUCCESS(Status))
195 {
196 /* Cleanup allocations and fail */
201 return Status;
202 }
203
204 /* Check if we should verify the registry */
205 if ((OperationType == HINIT_FILE) ||
206 (OperationType == HINIT_MEMORY) ||
207 (OperationType == HINIT_MEMORY_INPLACE) ||
208 (OperationType == HINIT_MAPFILE))
209 {
210 /* Verify integrity */
211 CM_CHECK_REGISTRY_STATUS CheckStatus = CmCheckRegistry(Hive, CheckFlags);
212 if (!CM_CHECK_REGISTRY_SUCCESS(CheckStatus))
213 {
214 /* Cleanup allocations and fail */
220 }
221 }
222
223 /* Reset the loading flag */
224 Hive->HiveIsLoading = FALSE;
225
226 /* Lock the hive list */
228
229 /* Insert this hive */
231
232 /* Release the lock */
234
235 /* Return the hive and success */
236 *CmHive = Hive;
237 return STATUS_SUCCESS;
238}
BOOLEAN NTAPI CmpFileWrite(IN PHHIVE RegistryHive, IN ULONG FileType, IN PULONG FileOffset, IN PVOID Buffer, IN SIZE_T BufferLength)
Definition: cmwraprs.c:99
BOOLEAN NTAPI CmpFileSetSize(_In_ PHHIVE RegistryHive, _In_ ULONG FileType, _In_ ULONG FileSize, _In_ ULONG OldFileSize)
Definition: cmwraprs.c:132
BOOLEAN NTAPI CmpFileFlush(IN PHHIVE RegistryHive, IN ULONG FileType, IN OUT PLARGE_INTEGER FileOffset, IN ULONG Length)
Definition: cmwraprs.c:192
BOOLEAN NTAPI CmpFileRead(IN PHHIVE RegistryHive, IN ULONG FileType, IN PULONG FileOffset, OUT PVOID Buffer, IN SIZE_T BufferLength)
Definition: cmwraprs.c:73
ULONG ERESOURCE
Definition: env_spec_w32.h:594
@ FileFsSizeInformation
Definition: from_kernel.h:221
#define HBLOCK_SIZE
Definition: hivedata.h:42
#define HINIT_MEMORY
Definition: hivedata.h:14
#define HFILE_TYPE_ALTERNATE
Definition: hivedata.h:36
#define HINIT_MAPFILE
Definition: hivedata.h:18
#define HFILE_TYPE_EXTERNAL
Definition: hivedata.h:35
#define HINIT_MEMORY_INPLACE
Definition: hivedata.h:16
#define HSECTOR_SIZE
Definition: hivedata.h:43
static IDispatch External
Definition: htmldoc.c:521
NTSYSAPI NTSTATUS NTAPI ZwQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_REGISTRY_CORRUPT
Definition: ntstatus.h:568
ULONG FlushCount
Definition: cmlib.h:356
PKTHREAD HiveSecurityLockOwner
Definition: cmlib.h:329
LIST_ENTRY NotifyList
Definition: cmlib.h:319
BOOLEAN Frozen
Definition: cmlib.h:345
LIST_ENTRY HiveList
Definition: cmlib.h:320
EX_PUSH_LOCK WriterLock
Definition: cmlib.h:325
PKTHREAD HiveLockOwner
Definition: cmlib.h:322
PERESOURCE FlusherLock
Definition: cmlib.h:327
PKTHREAD WriterLockOwner
Definition: cmlib.h:326
BOOLEAN GrowOnlyMode
Definition: cmlib.h:347
LIST_ENTRY KnodeConvertListHead
Definition: cmlib.h:350
EX_PUSH_LOCK SecurityLock
Definition: cmlib.h:328
PWORK_QUEUE_ITEM UnloadWorkItem
Definition: cmlib.h:346
LIST_ENTRY TrustClassEntry
Definition: cmlib.h:355
ULONG Flags
Definition: cmlib.h:354
CM_USE_COUNT_LOG UseCountLog
Definition: cmlib.h:352
LIST_ENTRY KcbConvertListHead
Definition: cmlib.h:349
PKEVENT UnloadEvent
Definition: cmlib.h:343
UNICODE_STRING FileUserName
Definition: cmlib.h:334
PFILE_OBJECT FileObject
Definition: cmlib.h:332
PCM_KEY_CONTROL_BLOCK RootKcb
Definition: cmlib.h:344
PCM_CELL_REMAP_BLOCK CellRemapArray
Definition: cmlib.h:351
ULONG GrowOffset
Definition: cmlib.h:348
EX_PUSH_LOCK HiveLock
Definition: cmlib.h:321
CM_USE_COUNT_LOG LockHiveLog
Definition: cmlib.h:353
USHORT Next
Definition: cmlib.h:307
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
#define max(a, b)
Definition: svc.c:63
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by CmInitSystem1(), CmpHasAlternateHiveDiverged(), CmpInitHiveFromFile(), CmpInitializeSystemHive(), CmSaveKey(), and CmSaveMergedKeys().

◆ CmpInitializeHiveList()

VOID NTAPI CmpInitializeHiveList ( VOID  )

Definition at line 1467 of file cmsysini.c.

1468{
1469 WCHAR FileBuffer[64], RegBuffer[64];
1470 PCWSTR ConfigPath;
1471 UNICODE_STRING TempName, FileName, RegName;
1472 HANDLE Thread;
1474 ULONG i;
1475 USHORT RegStart;
1477
1478 PAGED_CODE();
1479
1480 /* Reenable hive writes now */
1481 CmpNoWrite = FALSE;
1482
1483 /* Build the file name and registry name strings */
1484 RtlInitEmptyUnicodeString(&FileName, FileBuffer, sizeof(FileBuffer));
1485 RtlInitEmptyUnicodeString(&RegName, RegBuffer, sizeof(RegBuffer));
1486
1487 /* Now build the system root path */
1488 ConfigPath = CmpGetRegistryPath();
1489 RtlInitUnicodeString(&TempName, ConfigPath);
1491
1492 /* And build the registry root path */
1493 RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
1494 RtlAppendUnicodeStringToString(&RegName, &TempName);
1495 RegStart = RegName.Length;
1496
1497 /* Setup the event to synchronize workers */
1499
1500 /* Enter special boot condition */
1502
1503 /* Create the SD for the root hives */
1505
1506 /* Loop every hive we care about */
1507 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1508 {
1509 /* Make sure the list is set up */
1511
1512 /* Load this root hive as volatile, if opened in shared mode */
1515
1516 /* Create a thread to handle this hive */
1519 NULL,
1520 0,
1521 NULL,
1522 CmpLoadHiveThread,
1523 UlongToPtr(i));
1524 if (NT_SUCCESS(Status))
1525 {
1526 /* We don't care about the handle -- the thread self-terminates */
1527 ZwClose(Thread);
1528 }
1529 else
1530 {
1531 /* Can't imagine this happening */
1532 KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 3, i, Status);
1533 }
1534 }
1535
1536 /* Make sure we've reached the end of the list */
1538
1539 /* Wait for hive loading to finish */
1541 Executive,
1542 KernelMode,
1543 FALSE,
1544 NULL);
1545
1546 /* Exit the special boot condition and make sure all workers completed */
1549
1550 /* Loop hives again */
1551 for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
1552 {
1553 /* Make sure the thread ran and finished */
1554 ASSERT(CmpMachineHiveList[i].ThreadFinished == TRUE);
1555 ASSERT(CmpMachineHiveList[i].ThreadStarted == TRUE);
1556
1557 /* Check if this was a new hive */
1558 if (!CmpMachineHiveList[i].CmHive)
1559 {
1560 /* Make sure we allocated something */
1561 ASSERT(CmpMachineHiveList[i].CmHive2 != NULL);
1562
1563 /* Build the base name */
1564 RegName.Length = RegStart;
1565 RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
1566 RtlAppendUnicodeStringToString(&RegName, &TempName);
1567
1568 /* Check if this is a child of the root */
1569 if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
1570 {
1571 /* Then setup the whole name */
1573 RtlAppendUnicodeStringToString(&RegName, &TempName);
1574 }
1575
1576 /* Now link the hive to its master */
1577 Status = CmpLinkHiveToMaster(&RegName,
1578 NULL,
1579 CmpMachineHiveList[i].CmHive2,
1582 if (Status != STATUS_SUCCESS)
1583 {
1584 /* Linking needs to work */
1585 KeBugCheckEx(CONFIG_LIST_FAILED, 11, Status, i, (ULONG_PTR)&RegName);
1586 }
1587
1588 /* Check if we had to allocate a new hive */
1590 {
1591 /* Sync the new hive */
1592 //HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2));
1593 }
1594 }
1595
1596 /* Check if we created a new hive */
1597 if (CmpMachineHiveList[i].CmHive2)
1598 {
1599 /* Add to HiveList key */
1601 }
1602 }
1603
1604 /* Get rid of the SD */
1606
1607 /* Link SECURITY to SAM */
1608 CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM",
1609 L"\\Registry\\Machine\\SAM\\SAM");
1610
1611 /* Link S-1-5-18 to .Default */
1613 CmpLinkKeyToHive(L"\\Registry\\User\\S-1-5-18",
1614 L"\\Registry\\User\\.Default");
1616}
#define CM_NUMBER_OF_MACHINE_HIVES
Definition: cm.h:118
BOOLEAN NTAPI CmpLinkKeyToHive(_In_z_ PCWSTR LinkKeyName, _In_z_ PCWSTR TargetKeyName)
Definition: cmsysini.c:45
KEVENT CmpLoadWorkerEvent
Definition: cmsysini.c:21
static PCWSTR CmpGetRegistryPath(VOID)
Definition: cmsysini.c:1172
LONG CmpLoadWorkerIncrement
Definition: cmsysini.c:22
#define UlongToPtr(u)
Definition: config.h:106
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
@ SynchronizationEvent
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
ULONG HHiveFlags
Definition: cm.h:412
const uint16_t * PCWSTR
Definition: typedefs.h:57
@ Executive
Definition: ketypes.h:415

Referenced by CmpCmdInit().

◆ CmpInitializeMachineDependentConfiguration()

NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 21 of file cmhardwr.c.

22{
23 //
24 // Nothing to do on ARM
25 //
26 return STATUS_SUCCESS;
27}

Referenced by CmInitSystem1().

◆ CmpInitializeRegistryNode()

NTSTATUS NTAPI CmpInitializeRegistryNode ( IN PCONFIGURATION_COMPONENT_DATA  CurrentEntry,
IN HANDLE  NodeHandle,
OUT PHANDLE  NewHandle,
IN INTERFACE_TYPE  InterfaceType,
IN ULONG  BusNumber,
IN PUSHORT  DeviceIndexTable 
)

Definition at line 20 of file cmconfig.c.

26{
30 HANDLE KeyHandle, ParentHandle;
31 ANSI_STRING TempString;
32 CHAR TempBuffer[12];
33 WCHAR Buffer[12];
36
37 /* Get the component */
38 Component = &CurrentEntry->ComponentEntry;
39
40 /* Set system class components to ARC system type */
41 if (Component->Class == SystemClass) Component->Type = ArcSystem;
42
43 /* Create a key for the component */
45 &CmTypeName[Component->Type],
48 NULL);
52 0,
53 NULL,
54 0,
56 if (!NT_SUCCESS(Status)) return Status;
57
58 /* Check if this is anything but a system class component */
59 if (Component->Class != SystemClass)
60 {
61 /* Build the sub-component string */
62 RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
63 10,
64 12,
65 TempBuffer);
66 RtlInitAnsiString(&TempString, TempBuffer);
67
68 /* Convert it to Unicode */
69 RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
71 if (!NT_SUCCESS(Status))
72 {
74 return Status;
75 }
76
77 /* Create the key */
78 ParentHandle = KeyHandle;
80 &KeyName,
82 ParentHandle,
83 NULL);
87 0,
88 NULL,
89 0,
91 NtClose(ParentHandle);
92
93 /* Fail if the key couldn't be created, and make sure it's a new key */
94 if (!NT_SUCCESS(Status)) return Status;
96 }
97
98 /* Setup the component information key */
99 RtlInitUnicodeString(&ValueName, L"Component Information");
101 &ValueName,
102 0,
104 &Component->Flags,
106 ConfigurationDataLength) -
108 if (!NT_SUCCESS(Status))
109 {
110 /* Fail */
112 return Status;
113 }
114
115 /* Check if we have an identifier */
116 if (Component->IdentifierLength)
117 {
118 /* Build the string and convert it to Unicode */
119 RtlInitUnicodeString(&ValueName, L"Identifier");
120 RtlInitAnsiString(&TempString, Component->Identifier);
122 &TempString,
123 TRUE);
124 if (NT_SUCCESS(Status))
125 {
126 /* Save the identifier in the registry */
128 &ValueName,
129 0,
130 REG_SZ,
131 ValueData.Buffer,
132 ValueData.Length + sizeof(UNICODE_NULL));
134 }
135
136 /* Check for failure during conversion or registry write */
137 if (!NT_SUCCESS(Status))
138 {
139 /* Fail */
141 return Status;
142 }
143 }
144
145 /* Setup the configuration data string */
146 RtlInitUnicodeString(&ValueName, L"Configuration Data");
147
148 /* Check if we got configuration data */
149 if (CurrentEntry->ConfigurationData)
150 {
151 /* Calculate the total length and check if it fits into our buffer */
152 Length = Component->ConfigurationDataLength +
153 FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
155 {
156 ASSERTMSG("Component too large -- need reallocation!\n", FALSE);
157 }
158 else
159 {
160 /* Copy the data */
162 CurrentEntry->ConfigurationData,
163 Component->ConfigurationDataLength);
164 }
165 }
166 else
167 {
168 /* No configuration data, setup defaults */
172 Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
173 FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
174 }
175
176 /* Set the interface type and bus number */
179
180 /* Save the actual data */
182 &ValueName,
183 0,
186 Length);
187 if (!NT_SUCCESS(Status))
188 {
189 /* Fail */
191 }
192 else
193 {
194 /* Return the new handle */
195 *NewHandle = KeyHandle;
196 }
197
198 /* Return status */
199 return Status;
200}
UNICODE_STRING CmTypeName[]
_In_ PKSNODE_CREATE _In_ ACCESS_MASK _Out_ PHANDLE NodeHandle
Definition: ks.h:4548
NTSYSAPI NTSTATUS NTAPI RtlIntegerToChar(_In_ ULONG Value, _In_ ULONG Base, _In_ ULONG Length, _Out_ PCHAR String)
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define REG_BINARY
Definition: nt_native.h:1496
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
@ SystemClass
Definition: arc.h:90
@ ArcSystem
Definition: arc.h:104
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:463
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
_In_ ULONG Component
Definition: potypes.h:496
char CHAR
Definition: xmlstorage.h:175

Referenced by CmpInitializeMachineDependentConfiguration(), and CmpSetupConfigurationTree().

◆ CmpInitSecurityCache()

VOID NTAPI CmpInitSecurityCache ( IN PCMHIVE  Hive)

Definition at line 21 of file cmsecach.c.

22{
23 ULONG i;
24
25 /* Reset data */
26 Hive->SecurityCount = 0;
27 Hive->SecurityCacheSize = 0;
28 Hive->SecurityHitHint = -1;
29 Hive->SecurityCache = NULL;
30
31 /* Loop every security hash */
32 for (i = 0; i < CMP_SECURITY_HASH_LISTS; i++)
33 {
34 /* Initialize it */
35 InitializeListHead(&Hive->SecurityHash[i]);
36 }
37}
#define CMP_SECURITY_HASH_LISTS
Definition: cmlib.h:294

Referenced by CmGetSystemControlValues(), and CmpInitializeHive().

◆ CmpLazyFlush()

VOID NTAPI CmpLazyFlush ( VOID  )

Definition at line 157 of file cmlazy.c.

158{
160 PAGED_CODE();
161
162 /* Check if we should set the lazy flush timer */
164 {
165 /* Do it */
167 -10 * 1000 * 1000);
169 }
170}
ULONG CmpLazyFlushIntervalInSeconds
Definition: cmlazy.c:24

◆ CmpLinkHiveToMaster()

NTSTATUS NTAPI CmpLinkHiveToMaster ( IN PUNICODE_STRING  LinkName,
IN HANDLE  RootDirectory,
IN PCMHIVE  CmHive,
IN BOOLEAN  Allocate,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor 
)

Definition at line 802 of file cmsysini.c.

807{
810 CM_PARSE_CONTEXT ParseContext = {0};
812 PCM_KEY_BODY KeyBody;
813 PAGED_CODE();
814
815 /* Setup the object attributes */
817 LinkName,
821
822 /* Setup the parse context */
823 ParseContext.CreateLink = TRUE;
824 ParseContext.CreateOperation = TRUE;
825 ParseContext.ChildHive.KeyHive = &RegistryHive->Hive;
826
827 /* Check if we have a root keycell or if we need to create it */
828 if (Allocate)
829 {
830 /* Create it */
831 ParseContext.ChildHive.KeyCell = HCELL_NIL;
832 }
833 else
834 {
835 /* We have one */
836 ParseContext.ChildHive.KeyCell = RegistryHive->Hive.BaseBlock->RootCell;
837 }
838
839 /* Create the link node */
843 NULL,
845 (PVOID)&ParseContext,
846 &KeyHandle);
847 if (!NT_SUCCESS(Status)) return Status;
848
849 /* Mark the hive as clean */
850 RegistryHive->Hive.DirtyFlag = FALSE;
851
852 /* ReactOS Hack: Keep alive */
854 0,
857 (PVOID*)&KeyBody,
858 NULL);
860
861 /* Close the extra handle */
863 return STATUS_SUCCESS;
864}
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
CM_KEY_REFERENCE ChildHive
Definition: cm.h:438
BOOLEAN CreateLink
Definition: cm.h:440

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

◆ CmpLockHiveFlusherExclusive()

VOID NTAPI CmpLockHiveFlusherExclusive ( IN PCMHIVE  Hive)

Definition at line 2006 of file cmsysini.c.

2007{
2008 /* Lock the flusher. We should already be in a critical section */
2010 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2011 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2012 ExAcquireResourceExclusiveLite(Hive->FlusherLock, TRUE);
2013}
#define CMP_ASSERT_REGISTRY_LOCK_OR_LOADING(h)
Definition: cm_x.h:59
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
#define ExIsResourceAcquiredShared
Definition: exfuncs.h:348

Referenced by CmFlushKey(), CmLoadKey(), CmpDoFlushAll(), and CmpUnlinkHiveFromMaster().

◆ CmpLockHiveFlusherShared()

VOID NTAPI CmpLockHiveFlusherShared ( IN PCMHIVE  Hive)

Definition at line 2017 of file cmsysini.c.

2018{
2019 /* Lock the flusher. We should already be in a critical section */
2021 ASSERT((ExIsResourceAcquiredShared(Hive->FlusherLock) == 0) &&
2022 (ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) == 0));
2023 ExAcquireResourceSharedLite(Hive->FlusherLock, TRUE);
2024}
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmpCreateLinkNode(), CmpDoCreate(), and CmSetValueKey().

◆ CmpLockRegistry()

VOID NTAPI CmpLockRegistry ( VOID  )

Definition at line 1970 of file cmsysini.c.

1971{
1972 /* Enter a critical region */
1974
1975 /* Check if we have to starve writers */
1977 {
1978 /* Starve exlusive waiters */
1980 }
1981 else
1982 {
1983 /* Just grab the lock */
1985 }
1986}
LONG CmpFlushStarveWriters
Definition: cmlazy.c:27
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
BOOLEAN NTAPI ExAcquireSharedStarveExclusive(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:1068

Referenced by _Function_class_(), CmDeleteKey(), CmDeleteValueKey(), CmEnumerateKey(), CmEnumerateValueKey(), CmLoadKey(), CmpBuildHashStackAndLookupCache(), CmpDeleteKeyObject(), CmpQueryKeyName(), CmpSecurityMethod(), CmQueryKey(), CmQueryValueKey(), CmSaveKey(), CmSaveMergedKeys(), CmSetValueKey(), NtFlushKey(), and NtUnloadKey2().

◆ CmpLockRegistryExclusive()

VOID NTAPI CmpLockRegistryExclusive ( VOID  )

Definition at line 1957 of file cmsysini.c.

1958{
1959 /* Enter a critical region and lock the registry */
1962
1963 /* Sanity check */
1966}
PVOID CmpRegistryLockCallerCaller
Definition: cmsysini.c:24
PVOID CmpRegistryLockCaller
Definition: cmsysini.c:24
NTSYSAPI VOID NTAPI RtlGetCallersAddress(_Out_ PVOID *CallersAddress, _Out_ PVOID *CallersCaller)
Definition: except.c:22

Referenced by _Function_class_(), CmGetSystemDriverList(), CmLoadKey(), CmShutdownSystem(), NtInitializeRegistry(), NtQueryOpenSubKeys(), and NtUnloadKey2().

◆ CmpOpenHiveFiles()

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 
)

Definition at line 273 of file cminit.c.

283{
287 UNICODE_STRING FullName, ExtensionName;
288 PWCHAR NameBuffer;
292 ULONG AttributeFlags, ShareMode, DesiredAccess, CreateDisposition, IoFlags;
293 USHORT CompressionState;
295 FILE_FS_SIZE_INFORMATION FsSizeInformation;
296
297 /* Create event */
299 if (!NT_SUCCESS(Status)) return Status;
300
301 /* Initialize the full name */
302 RtlInitEmptyUnicodeString(&FullName, NULL, 0);
303 Length = BaseName->Length;
304
305 /* Check if we have an extension */
306 if (Extension)
307 {
308 /* Update the name length */
309 Length += (USHORT)wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
310
311 /* Allocate the buffer for the full name */
313 if (!NameBuffer)
314 {
315 /* Fail */
318 return STATUS_NO_MEMORY;
319 }
320
321 /* Build the full name */
322 FullName.Buffer = NameBuffer;
324 RtlCopyUnicodeString(&FullName, BaseName);
325 }
326 else
327 {
328 /* The base name is the full name */
329 FullName = *BaseName;
330 NameBuffer = NULL;
331 }
332
333 /* Initialize the attributes */
335 &FullName,
337 NULL,
338 NULL);
339
340 /* Check if we can create the hive */
341 if (CreateAllowed && !CmpShareSystemHives)
342 {
343 /* Open only or create */
345 }
346 else
347 {
348 /* Open only */
350 }
351
352 /* Setup the flags */
353 // FIXME : FILE_OPEN_FOR_BACKUP_INTENT is unimplemented and breaks 3rd stage boot
354 IoFlags = //FILE_OPEN_FOR_BACKUP_INTENT |
357 (NoBuffering ? FILE_NO_INTERMEDIATE_BUFFERING : 0);
358
359 /* Set share and access modes */
361 {
362 /* We're on Live CD or otherwise sharing */
364 ShareMode = FILE_SHARE_READ;
365 }
366 else
367 {
368 /* We want to write exclusively */
369 ShareMode = 0;
371 }
372
373 /* Default attributes */
374 AttributeFlags = FILE_ATTRIBUTE_NORMAL;
375
376 /* Now create the file.
377 * Note: We use FILE_SYNCHRONOUS_IO_NONALERT here to simplify CmpFileRead/CmpFileWrite.
378 * Windows does async I/O and therefore does not use this flag (or SYNCHRONIZE).
379 */
380 Status = ZwCreateFile(Primary,
384 NULL,
385 AttributeFlags,
386 ShareMode,
389 NULL,
390 0);
391 /* Check if anything failed until now */
392 if (!NT_SUCCESS(Status))
393 {
394 DPRINT1("ZwCreateFile(%wZ) failed, Status 0x%08lx.\n", ObjectAttributes.ObjectName, Status);
395
396 /* Close handles and free buffers */
397 if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
400 *Primary = NULL;
401 return Status;
402 }
403
404 if (MarkAsSystemHive)
405 {
406 /* We opened it, mark it as a system hive */
407 Status = ZwFsControlFile(*Primary,
409 NULL,
410 NULL,
413 NULL,
414 0,
415 NULL,
416 0);
417 if (Status == STATUS_PENDING)
418 {
419 /* Wait for completion */
421 Executive,
423 FALSE,
424 NULL);
426 }
427
428 /* If we don't support it, ignore the failure */
430
431 if (!NT_SUCCESS(Status))
432 {
433 /* Close handles and free buffers */
434 if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
437 ZwClose(*Primary);
438 *Primary = NULL;
439 return Status;
440 }
441 }
442
443 /* Disable compression */
444 CompressionState = 0;
445 Status = ZwFsControlFile(*Primary,
447 NULL,
448 NULL,
451 &CompressionState,
452 sizeof(CompressionState),
453 NULL,
454 0);
455 if (Status == STATUS_PENDING)
456 {
457 /* Wait for completion */
459 Executive,
461 FALSE,
462 NULL);
463 }
464
465 /* Get the disposition */
466 *PrimaryDisposition = (ULONG)IoStatusBlock.Information;
468 {
469 /* Check how large the file is */
470 Status = ZwQueryInformationFile(*Primary,
473 sizeof(FileInformation),
475 if (NT_SUCCESS(Status))
476 {
477 /* Check if it's 0 bytes */
478 if (!FileInformation.EndOfFile.QuadPart)
479 {
480 /* Assume it's a new file */
481 *PrimaryDisposition = FILE_CREATED;
482 }
483 }
484 }
485
486 /* Check if the caller wants cluster size returned */
487 if (ClusterSize)
488 {
489 /* Query it */
492 &FsSizeInformation,
493 sizeof(FsSizeInformation),
495 if (!NT_SUCCESS(Status))
496 {
497 /* Close handles and free buffers */
498 if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
501 return Status;
502 }
503
504 /* Check if the sector size is invalid */
505 if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE)
506 {
507 /* Close handles and free buffers */
508 if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
512 }
513
514 /* Return cluster size */
515 *ClusterSize = max(1, FsSizeInformation.BytesPerSector / HSECTOR_SIZE);
516 }
517
518 /* Check if we don't need to create a log file */
519 if (!Extension)
520 {
521 /* We're done, close handles */
524 return STATUS_SUCCESS;
525 }
526
527 /* Check if we can create the hive */
529 if (*PrimaryDisposition == FILE_CREATED)
530 {
531 /* Over-write the existing log file, since this is a new hive */
533 }
534
535 /* Setup the name */
536 RtlInitUnicodeString(&ExtensionName, Extension);
538
539 /* Initialize the attributes */
541 &FullName,
543 NULL,
544 NULL);
545
546 /* Setup the flags */
548
549 /* Check if this is a log file */
550 if (!_wcsnicmp(Extension, L".log", 4))
551 {
552 /* Hide log files */
553 AttributeFlags |= FILE_ATTRIBUTE_HIDDEN;
554 }
555
556 /* Now create the file.
557 * Note: We use FILE_SYNCHRONOUS_IO_NONALERT here to simplify CmpFileRead/CmpFileWrite.
558 * Windows does async I/O and therefore does not use this flag (or SYNCHRONIZE).
559 */
560 Status = ZwCreateFile(Log,
564 NULL,
565 AttributeFlags,
566 ShareMode,
569 NULL,
570 0);
571 if (NT_SUCCESS(Status) && MarkAsSystemHive)
572 {
573 /* We opened it, mark it as a system hive */
574 Status = ZwFsControlFile(*Log,
576 NULL,
577 NULL,
580 NULL,
581 0,
582 NULL,
583 0);
584 if (Status == STATUS_PENDING)
585 {
586 /* Wait for completion */
588 Executive,
590 FALSE,
591 NULL);
593 }
594
595 /* If we don't support it, ignore the failure */
597
598 /* If we failed, close the handle */
599 if (!NT_SUCCESS(Status)) ZwClose(*Log);
600 }
601
602 /* Check if anything failed until now */
603 if (!NT_SUCCESS(Status))
604 {
605 /* Clear the handle */
606 *Log = NULL;
607 }
608 else
609 {
610 /* Disable compression */
611 Status = ZwFsControlFile(*Log,
613 NULL,
614 NULL,
617 &CompressionState,
618 sizeof(CompressionState),
619 NULL,
620 0);
621 if (Status == STATUS_PENDING)
622 {
623 /* Wait for completion */
625 Executive,
627 FALSE,
628 NULL);
629 }
630
631 /* Return the disposition */
632 *LogDisposition = (ULONG)IoStatusBlock.Information;
633 }
634
635 /* We're done, close handles and free buffers */
636 if (NameBuffer) ExFreePoolWithTag(NameBuffer, TAG_CM);
639 return STATUS_SUCCESS;
640}
DWORD ClusterSize
Definition: format.c:67
NTSTATUS NTAPI CmpCreateEvent(IN EVENT_TYPE EventType, OUT PHANDLE EventHandle, OUT PKEVENT *Event)
Definition: cmwraprs.c:19
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_RANDOM_ACCESS
Definition: from_kernel.h:38
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FSCTL_MARK_AS_SYSTEM_HIVE
Definition: nt_native.h:845
#define FSCTL_SET_COMPRESSION
Definition: nt_native.h:842
@ NotificationEvent
NTSYSAPI NTSTATUS NTAPI ZwFsControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
#define STATUS_CANNOT_LOAD_REGISTRY_FILE
Definition: ntstatus.h:668
#define FileStandardInformation
Definition: propsheet.cpp:61
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG _Out_opt_ PULONG CreateDisposition
Definition: wdfregistry.h:120
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648

Referenced by _Function_class_(), and CmpInitHiveFromFile().

◆ CmpParseKey()

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 
)

Definition at line 1848 of file cmparse.c.

1858{
1860 PCM_KEY_CONTROL_BLOCK Kcb, ParentKcb;
1861 PHHIVE Hive = NULL;
1863 HCELL_INDEX Cell = HCELL_NIL, NextCell;
1864 PHHIVE HiveToRelease = NULL;
1865 HCELL_INDEX CellToRelease = HCELL_NIL;
1866 UNICODE_STRING Current, NextName;
1867 PCM_PARSE_CONTEXT ParseContext = Context;
1868 ULONG TotalRemainingSubkeys = 0, MatchRemainSubkeyLevel = 0, TotalSubkeys = 0;
1869 ULONG LockedKcbArray[CMP_KCBS_IN_ARRAY_LIMIT];
1870 PULONG LockedKcbs;
1871 BOOLEAN IsKeyCached = FALSE;
1872 BOOLEAN Result, Last;
1873 PAGED_CODE();
1874
1875 /* Loop path separators at the end */
1876 while (RemainingName->Length &&
1877 (RemainingName->Buffer[(RemainingName->Length / sizeof(WCHAR)) - 1] ==
1879 {
1880 /* Remove path separator */
1881 RemainingName->Length -= sizeof(WCHAR);
1882 }
1883
1884 /* Fail if this isn't a key object */
1886
1887 /* Copy the remaining name */
1888 Current = *RemainingName;
1889
1890 /* Check if this is a create */
1891 if (!ParseContext || !ParseContext->CreateOperation)
1892 {
1893 /* It isn't, so no context */
1894 ParseContext = NULL;
1895 }
1896
1897 /* Grab the KCB */
1898 Kcb = ((PCM_KEY_BODY)ParseObject)->KeyControlBlock;
1899
1900 /* Sanity check */
1901 ASSERT(Kcb != NULL);
1902
1903 /* Fail if the key was marked as deleted */
1904 if (Kcb->Delete)
1905 return STATUS_KEY_DELETED;
1906
1907 /* Lookup in the cache */
1909 &Kcb,
1910 &Current,
1911 &Hive,
1912 &Cell,
1913 &TotalRemainingSubkeys,
1914 &MatchRemainSubkeyLevel,
1915 &TotalSubkeys,
1916 LockedKcbArray,
1917 &LockedKcbs);
1919 if (!NT_SUCCESS(Status))
1920 {
1921 DPRINT1("Failed to look in cache, stop parsing (Status 0x%lx)\n", Status);
1922 ParentKcb = NULL;
1923 goto Quickie;
1924 }
1925
1926 /* This is now the parent */
1927 ParentKcb = Kcb;
1928
1929 /* Sanity check */
1930 ASSERT(ParentKcb != NULL);
1931
1932 /* Don't do anything if we're being deleted */
1933 if (Kcb->Delete)
1934 {
1936 goto Quickie;
1937 }
1938
1939 /* Check if everything was found cached */
1940 if (!TotalRemainingSubkeys)
1941 {
1942 /*
1943 * We don't have any remaining subkey levels so we're good
1944 * that we have an already perfect candidate for a KCB, just
1945 * do the open directly.
1946 */
1947 DPRINT("No remaining subkeys, the KCB points to the actual key\n");
1948 IsKeyCached = TRUE;
1949 goto KeyCachedOpenNow;
1950 }
1951
1952 /* Check if we have a matching level */
1953 if (MatchRemainSubkeyLevel)
1954 {
1955 /*
1956 * We have a matching level, check if that matches
1957 * with the total levels of subkeys. Do the open directly
1958 * if that is the case, because the whole subkeys levels
1959 * is cached.
1960 */
1961 if (MatchRemainSubkeyLevel == TotalSubkeys)
1962 {
1963 DPRINT("We have a full matching level, open the key now\n");
1964 IsKeyCached = TRUE;
1965 goto KeyCachedOpenNow;
1966 }
1967
1968 /*
1969 * We only have a partial match, make sure we did not
1970 * get mismatched hive data.
1971 */
1972 ASSERT(Hive == Kcb->KeyHive);
1973 ASSERT(Cell == Kcb->KeyCell);
1974 }
1975
1976 /*
1977 * FIXME: Currently the registry parser doesn't check for fake
1978 * KCBs. CmpCreateKeyControlBlock does have the necessary implementation
1979 * to create such fake keys but we don't create these fake keys anywhere.
1980 * When we will do, we must improve the registry parser routine to handle
1981 * fake keys a bit differently here.
1982 */
1983
1984 /* Check if this is a symlink */
1985 if (Kcb->Flags & KEY_SYM_LINK)
1986 {
1987 /* Get the next name */
1988 Result = CmpGetNextName(&Current, &NextName, &Last);
1989 Current.Buffer = NextName.Buffer;
1990
1991 /* Validate the current name string length */
1992 if (Current.Length + NextName.Length > MAXUSHORT)
1993 {
1994 /* too long */
1996 goto Quickie;
1997 }
1998 Current.Length += NextName.Length;
1999
2000 /* Validate the current name string maximum length */
2001 if (Current.MaximumLength + NextName.MaximumLength > MAXUSHORT)
2002 {
2003 /* too long */
2005 goto Quickie;
2006 }
2007 Current.MaximumLength += NextName.MaximumLength;
2008
2009 /* CmpGetSymbolicLink doesn't want a lock */
2010 CmpUnLockKcbArray(LockedKcbs);
2011 LockedKcbs = NULL;
2012
2013 /* Parse the symlink */
2014 if (CmpGetSymbolicLink(Hive,
2015 CompleteName,
2016 Kcb,
2017 &Current))
2018 {
2019 /* Symlink parse succeeded */
2021 }
2022 else
2023 {
2024 /* Couldn't find symlink */
2026 }
2027
2028 /* We're done */
2029 goto Quickie;
2030 }
2031
2032 /* Get the key node */
2033 Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
2034 if (!Node)
2035 {
2037 goto Quickie;
2038 }
2039
2040 /* Start parsing */
2042 while (TRUE)
2043 {
2044 /* Get the next component */
2045 Result = CmpGetNextName(&Current, &NextName, &Last);
2046 if (Result && NextName.Length)
2047 {
2048 /* See if this is a sym link */
2049 if (!(Kcb->Flags & KEY_SYM_LINK))
2050 {
2051 /* Find the subkey */
2052 NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
2053 if (NextCell != HCELL_NIL)
2054 {
2055 /* Get the new node */
2056 Cell = NextCell;
2057 Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
2058 ASSERT(Node);
2059
2060 /* Check if this was the last key */
2061 if (Last)
2062 {
2063 /* Is this an exit node */
2064 if (Node->Flags & KEY_HIVE_EXIT)
2065 {
2066 /* Handle it */
2067 CmpHandleExitNode(&Hive,
2068 &Cell,
2069 &Node,
2070 &HiveToRelease,
2071 &CellToRelease);
2072 if (!Node)
2073 {
2074 /* Fail */
2076 break;
2077 }
2078 }
2079
2080KeyCachedOpenNow:
2081 /* Do the open */
2082 Status = CmpDoOpen(Hive,
2083 Cell,
2084 Node,
2086 AccessMode,
2087 Attributes,
2088 ParseContext,
2090 &Kcb,
2091 LockedKcbs,
2092 &NextName,
2093 Object);
2094 if (Status == STATUS_REPARSE)
2095 {
2096 /* CmpGetSymbolicLink doesn't want a lock */
2097 CmpUnLockKcbArray(LockedKcbs);
2098 LockedKcbs = NULL;
2099
2100 /* Parse the symlink */
2101 if (!CmpGetSymbolicLink(Hive,
2102 CompleteName,
2103 Kcb,
2104 NULL))
2105 {
2106 /* Symlink parse failed */
2108 }
2109 }
2110
2111 /* We are done */
2112 break;
2113 }
2114
2115 /* Is this an exit node */
2116 if (Node->Flags & KEY_HIVE_EXIT)
2117 {
2118 /* Handle it */
2119 CmpHandleExitNode(&Hive,
2120 &Cell,
2121 &Node,
2122 &HiveToRelease,
2123 &CellToRelease);
2124 if (!Node)
2125 {
2126 /* Fail */
2128 break;
2129 }
2130 }
2131
2132 /* Create a KCB for this key */
2133 Kcb = CmpCreateKeyControlBlock(Hive,
2134 Cell,
2135 Node,
2136 ParentKcb,
2138 &NextName);
2139 if (!Kcb)
2140 {
2141 /* Fail */
2143 break;
2144 }
2145
2146 /* Dereference the parent and set the new one */
2148 ParentKcb = Kcb;
2149 }
2150 else
2151 {
2152 /* Check if this was the last key for a create */
2153 if (Last && ParseContext)
2154 {
2155 /* Check if we're doing a link node */
2156 if (ParseContext->CreateLink)
2157 {
2158 /* The only thing we should see */
2160 Cell,
2162 NextName,
2163 AccessMode,
2164 Attributes,
2165 ParseContext,
2166 ParentKcb,
2167 LockedKcbs,
2168 Object);
2169 }
2170 else if (Hive == &CmiVolatileHive->Hive && CmpNoVolatileCreates)
2171 {
2172 /* Creating keys in the master hive is not allowed */
2174 }
2175 else
2176 {
2177 /* Do the create */
2178 Status = CmpDoCreate(Hive,
2179 Cell,
2181 &NextName,
2182 AccessMode,
2183 ParseContext,
2184 ParentKcb,
2185 Object);
2186 }
2187
2188 /* Check for reparse (in this case, someone beat us) */
2189 if (Status == STATUS_REPARSE) break;
2190
2191 /* Update disposition */
2192 ParseContext->Disposition = REG_CREATED_NEW_KEY;
2193 break;
2194 }
2195 else
2196 {
2197 /* Key not found */
2199 break;
2200 }
2201 }
2202 }
2203 else
2204 {
2205 /* Save the next name */
2206 Current.Buffer = NextName.Buffer;
2207
2208 /* Validate the current name string length */
2209 if (Current.Length + NextName.Length > MAXUSHORT)
2210 {
2211 /* too long */
2213 break;
2214 }
2215 Current.Length += NextName.Length;
2216
2217 /* Validate the current name string maximum length */
2218 if (Current.MaximumLength + NextName.MaximumLength > MAXUSHORT)
2219 {
2220 /* too long */
2222 break;
2223 }
2224 Current.MaximumLength += NextName.MaximumLength;
2225
2226 /* CmpGetSymbolicLink doesn't want a lock */
2227 CmpUnLockKcbArray(LockedKcbs);
2228 LockedKcbs = NULL;
2229
2230 /* Parse the symlink */
2231 if (CmpGetSymbolicLink(Hive,
2232 CompleteName,
2233 Kcb,
2234 &Current))
2235 {
2236 /* Symlink parse succeeded */
2238 }
2239 else
2240 {
2241 /* Couldn't find symlink */
2243 }
2244
2245 /* We're done */
2246 break;
2247 }
2248 }
2249 else if (Result && Last)
2250 {
2251 /* Opening the root. Is this an exit node? */
2252 if (Node->Flags & KEY_HIVE_EXIT)
2253 {
2254 /* Handle it */
2255 CmpHandleExitNode(&Hive,
2256 &Cell,
2257 &Node,
2258 &HiveToRelease,
2259 &CellToRelease);
2260 if (!Node)
2261 {
2262 /* Fail */
2264 break;
2265 }
2266 }
2267
2268 /* Do the open */
2269 Status = CmpDoOpen(Hive,
2270 Cell,
2271 Node,
2273 AccessMode,
2274 Attributes,
2275 ParseContext,
2277 &Kcb,
2278 LockedKcbs,
2279 &NextName,
2280 Object);
2281 if (Status == STATUS_REPARSE)
2282 {
2283 /* Nothing to do */
2284 }
2285
2286 /* We're done */
2287 break;
2288 }
2289 else
2290 {
2291 /* Bogus */
2293 break;
2294 }
2295 }
2296
2297Quickie:
2298 /* Unlock all the KCBs */
2299 if (LockedKcbs != NULL)
2300 {
2301 CmpUnLockKcbArray(LockedKcbs);
2302 }
2303
2304 /* Dereference the parent if it exists */
2305 if (ParentKcb)
2307
2308 /* Unlock the registry */
2310 return Status;
2311}
#define CMP_OPEN_KCB_NO_CREATE
Definition: cm.h:90
VOID CmpUnLockKcbArray(_In_ PULONG KcbArray)
Unlocks a number of KCBs provided by a KCB array.
Definition: cmkcbncb.c:1145
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: cmkcbncb.c:655
VOID NTAPI CmpDereferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:571
NTSTATUS NTAPI CmpBuildHashStackAndLookupCache(_In_ PCM_KEY_BODY ParseObject, _Inout_ PCM_KEY_CONTROL_BLOCK *Kcb, _In_ PUNICODE_STRING Current, _Out_ PHHIVE *Hive, _Out_ PHCELL_INDEX Cell, _Out_ PULONG TotalRemainingSubkeys, _Out_ PULONG MatchRemainSubkeyLevel, _Out_ PULONG TotalSubkeys, _Inout_ PULONG OuterStackArray, _Out_ PULONG *LockedKcbs)
Builds a hash stack cache and looks up in the pool cache for a matching key pathname.
Definition: cmparse.c:1696
BOOLEAN NTAPI CmpGetSymbolicLink(IN PHHIVE Hive, IN OUT PUNICODE_STRING ObjectName, IN OUT PCM_KEY_CONTROL_BLOCK SymbolicKcb, IN PUNICODE_STRING RemainingName OPTIONAL)
Definition: cmparse.c:75
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: cmparse.c:830
VOID NTAPI CmpHandleExitNode(IN OUT PHHIVE *Hive, IN OUT HCELL_INDEX *Cell, IN OUT PCM_KEY_NODE *KeyNode, IN OUT PHHIVE *ReleaseHive, IN OUT HCELL_INDEX *ReleaseCell)
Definition: cmparse.c:1080
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 ParseContext, IN PCM_KEY_CONTROL_BLOCK ParentKcb, OUT PVOID *Object)
Definition: cmparse.c:404
BOOLEAN NTAPI CmpGetNextName(IN OUT PUNICODE_STRING RemainingName, OUT PUNICODE_STRING NextName, OUT PBOOLEAN LastName)
Definition: cmparse.c:21
ObjectType
Definition: metafile.c:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
ULONG Disposition
Definition: cm.h:437
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by CmpCreateObjectTypes().

◆ CmpQueryKeyName()

NTSTATUS NTAPI CmpQueryKeyName ( IN PVOID  Object,
IN BOOLEAN  HasObjectName,
OUT POBJECT_NAME_INFORMATION  ObjectNameInfo,
IN ULONG  Length,
OUT PULONG  ReturnLength,
IN KPROCESSOR_MODE  AccessMode 
)

◆ CmpQueryKeyValueData()

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 at line 327 of file cmvalche.c.

336{
338 PCELL_DATA CellData;
339 USHORT NameSize;
340 ULONG Size, MinimumSize, SizeLeft, KeySize, AlignedData = 0, DataOffset;
342 BOOLEAN IsSmall, BufferAllocated = FALSE;
343 HCELL_INDEX CellToRelease = HCELL_NIL;
345
346 /* Get the value data */
347 CellData = (PCELL_DATA)ValueKey;
348
349 /* Check if the value is compressed */
350 if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
351 {
352 /* Get the compressed name size */
353 NameSize = CmpCompressedNameSize(CellData->u.KeyValue.Name,
354 CellData->u.KeyValue.NameLength);
355 }
356 else
357 {
358 /* Get the real size */
359 NameSize = CellData->u.KeyValue.NameLength;
360 }
361
362 /* Check what kind of information the caller is requesting */
364 {
365 /* Basic information */
367
368 /* This is how much size we'll need */
370
371 /* This is the minimum we can work with */
373
374 /* Return the size we'd like, and assume success */
377
378 /* Check if the caller gave us below our minimum */
379 if (Length < MinimumSize)
380 {
381 /* Then we must fail */
383 break;
384 }
385
386 /* Fill out the basic information */
387 Info->KeyValueBasicInformation.TitleIndex = 0;
388 Info->KeyValueBasicInformation.Type = CellData->u.KeyValue.Type;
389 Info->KeyValueBasicInformation.NameLength = NameSize;
390
391 /* Now only the name is left */
392 SizeLeft = Length - MinimumSize;
393 Size = NameSize;
394
395 /* Check if the remaining buffer is too small for the name */
396 if (SizeLeft < Size)
397 {
398 /* Copy only as much as can fit, and tell the caller */
399 Size = SizeLeft;
401 }
402
403 /* Check if this is a compressed name */
404 if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
405 {
406 /* Copy as much as we can of the compressed name */
407 CmpCopyCompressedName(Info->KeyValueBasicInformation.Name,
408 Size,
409 CellData->u.KeyValue.Name,
410 CellData->u.KeyValue.NameLength);
411 }
412 else
413 {
414 /* Copy as much as we can of the raw name */
415 RtlCopyMemory(Info->KeyValueBasicInformation.Name,
416 CellData->u.KeyValue.Name,
417 Size);
418 }
419
420 /* We're all done */
421 break;
422
423 /* Full key information */
426
427 /* Check if this is a small key and compute key size */
428 IsSmall = CmpIsKeyValueSmall(&KeySize,
429 CellData->u.KeyValue.DataLength);
430
431 /* Calculate the total size required */
433 NameSize +
434 KeySize;
435
436 /* And this is the least we can work with */
438
439 /* Check if there's any key data */
440 if (KeySize > 0)
441 {
442 /* Calculate the data offset */
443 DataOffset = Size - KeySize;
444
445#ifdef _WIN64
446 /* On 64-bit, always align to 8 bytes */
447 AlignedData = ALIGN_UP(DataOffset, ULONGLONG);
448#else
449 /* On 32-bit, align the offset to 4 or 8 bytes */
451 {
452 AlignedData = ALIGN_UP(DataOffset, ULONGLONG);
453 }
454 else
455 {
456 AlignedData = ALIGN_UP(DataOffset, ULONG);
457 }
458#endif
459 /* If alignment was required, we'll need more space */
460 if (AlignedData > DataOffset) Size += (AlignedData-DataOffset);
461 }
462
463 /* Tell the caller the size we'll finally need, and set success */
466
467 /* Check if the caller is giving us too little */
468 if (Length < MinimumSize)
469 {
470 /* Then fail right now */
472 break;
473 }
474
475 /* Fill out the basic information */
476 Info->KeyValueFullInformation.TitleIndex = 0;
477 Info->KeyValueFullInformation.Type = CellData->u.KeyValue.Type;
478 Info->KeyValueFullInformation.DataLength = KeySize;
479 Info->KeyValueFullInformation.NameLength = NameSize;
480
481 /* Only the name is left now */
482 SizeLeft = Length - MinimumSize;
483 Size = NameSize;
484
485 /* Check if the name fits */
486 if (SizeLeft < Size)
487 {
488 /* It doesn't, truncate what we'll copy, and tell the caller */
489 Size = SizeLeft;
491 }
492
493 /* Check if this key value is compressed */
494 if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
495 {
496 /* It is, copy the compressed name */
497 CmpCopyCompressedName(Info->KeyValueFullInformation.Name,
498 Size,
499 CellData->u.KeyValue.Name,
500 CellData->u.KeyValue.NameLength);
501 }
502 else
503 {
504 /* It's not, copy the raw name */
505 RtlCopyMemory(Info->KeyValueFullInformation.Name,
506 CellData->u.KeyValue.Name,
507 Size);
508 }
509
510 /* Now check if the key had any data */
511 if (KeySize > 0)
512 {
513 /* Was it a small key? */
514 if (IsSmall)
515 {
516 /* Then the data is directly into the cell */
517 Buffer = &CellData->u.KeyValue.Data;
518 }
519 else
520 {
521 /* Otherwise, we must retrieve it from the value cache */
523 CachedValue,
524 CellData,
525 ValueIsCached,
526 &Buffer,
527 &BufferAllocated,
528 &CellToRelease);
529 if (Result != SearchSuccess)
530 {
531 /* We failed, nothing should be allocated */
532 ASSERT(Buffer == NULL);
533 ASSERT(BufferAllocated == FALSE);
535 }
536 }
537
538 /* Now that we know we truly have data, set its offset */
539 Info->KeyValueFullInformation.DataOffset = AlignedData;
540
541 /* Only the data remains to be copied */
542 SizeLeft = (((LONG)Length - (LONG)AlignedData) < 0) ?
543 0 : (Length - AlignedData);
544 Size = KeySize;
545
546 /* Check if the caller has no space for it */
547 if (SizeLeft < Size)
548 {
549 /* Truncate what we'll copy, and tell the caller */
550 Size = SizeLeft;
552 }
553
554 /* Sanity check */
555 ASSERT(IsSmall ? (Size <= CM_KEY_VALUE_SMALL) : TRUE);
556
557 /* Make sure we have a valid buffer */
558 if (Buffer)
559 {
560 /* Copy the data into the aligned offset */
561 RtlCopyMemory((PVOID)((ULONG_PTR)Info + AlignedData),
562 Buffer,
563 Size);
564 }
565 }
566 else
567 {
568 /* We don't have any data, set the offset to -1, not 0! */
569 Info->KeyValueFullInformation.DataOffset = 0xFFFFFFFF;
570 }
571
572 /* We're done! */
573 break;
574
575 /* Partial information requested (no name or alignment!) */
578
579 /* Check if this is a small key and compute key size */
580 IsSmall = CmpIsKeyValueSmall(&KeySize,
581 CellData->u.KeyValue.DataLength);
582
583 /* Calculate the total size required and the least we can work with */
585 {
588 }
589 else
590 {
593 }
594
595 /* Tell the caller the size we'll finally need, and set success */
598
599 /* Check if the caller is giving us too little */
600 if (Length < MinimumSize)
601 {
602 /* Then fail right now */
604 break;
605 }
606
607 /* Fill out the basic information */
609 {
610 Info->KeyValuePartialInformationAlign64.Type = CellData->u.KeyValue.Type;
611 Info->KeyValuePartialInformationAlign64.DataLength = KeySize;
612 }
613 else
614 {
615 Info->KeyValuePartialInformation.TitleIndex = 0;
616 Info->KeyValuePartialInformation.Type = CellData->u.KeyValue.Type;
617 Info->KeyValuePartialInformation.DataLength = KeySize;
618 }
619
620 /* Now check if the key had any data */
621 if (KeySize > 0)
622 {
623 /* Was it a small key? */
624 if (IsSmall)
625 {
626 /* Then the data is directly into the cell */
627 Buffer = &CellData->u.KeyValue.Data;
628 }
629 else
630 {
631 /* Otherwise, we must retrieve it from the value cache */
633 CachedValue,
634 CellData,
635 ValueIsCached,
636 &Buffer,
637 &BufferAllocated,
638 &CellToRelease);
639 if (Result != SearchSuccess)
640 {
641 /* We failed, nothing should be allocated */
642 ASSERT(Buffer == NULL);
643 ASSERT(BufferAllocated == FALSE);
645 }
646 }
647
648 /* Only the data remains to be copied */
649 SizeLeft = Length - MinimumSize;
650 Size = KeySize;
651
652 /* Check if the caller has no space for it */
653 if (SizeLeft < Size)
654 {
655 /* Truncate what we'll copy, and tell the caller */
656 Size = SizeLeft;
658 }
659
660 /* Sanity check */
661 ASSERT(IsSmall ? (Size <= CM_KEY_VALUE_SMALL) : TRUE);
662
663 /* Make sure we have a valid buffer */
664 if (Buffer)
665 {
666 /* Copy the data into the aligned offset */
668 {
669 RtlCopyMemory(Info->KeyValuePartialInformationAlign64.Data,
670 Buffer,
671 Size);
672 }
673 else
674 {
675 RtlCopyMemory(Info->KeyValuePartialInformation.Data,
676 Buffer,
677 Size);
678 }
679 }
680 }
681
682 /* We're done! */
683 break;
684
685 /* Other information class */
686 default:
687
688 /* We got some class that we don't support */
689 DPRINT1("Caller requested unknown class: %lx\n", KeyValueInformationClass);
691 break;
692 }
693
694 /* Return the search result as well */
695 return Result;
696}
struct _KEY_VALUE_INFORMATION * PKEY_VALUE_INFORMATION
@ KeyValuePartialInformationAlign64
Definition: reg.c:103
@ KeyValueFullInformationAlign64
Definition: reg.c:102
@ KeyValueBasicInformation
Definition: nt_native.h:1180
@ KeyValuePartialInformation
Definition: nt_native.h:1182
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
CM_KEY_VALUE KeyValue
Definition: cmdata.h:201
ULONG Type
Definition: cmdata.h:128
HCELL_INDEX Data
Definition: cmdata.h:127
ULONG DataLength
Definition: cmdata.h:126
uint64_t ULONGLONG
Definition: typedefs.h:67
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by CmEnumerateValueKey(), and CmQueryValueKey().

◆ CmpReferenceKeyControlBlock()

BOOLEAN NTAPI CmpReferenceKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 357 of file cmkcbncb.c.

358{
360 "%s - Referencing KCB: %p\n", __FUNCTION__, Kcb);
361
362 /* Check if this is the KCB's first reference */
363 if (Kcb->RefCount == 0)
364 {
365 /* Check if the KCB is locked in shared mode */
366 if (!CmpIsKcbLockedExclusive(Kcb))
367 {
368 /* Convert it to exclusive */
370 {
371 /* Set the delayed close index so that we can be ignored */
372 Kcb->DelayedCloseIndex = 1;
373
374 /* Increase the reference count while we release the lock */
375 InterlockedIncrement((PLONG)&Kcb->RefCount);
376
377 /* Go from shared to exclusive */
379
380 /* Decrement the reference count; the lock is now held again */
381 InterlockedDecrement((PLONG)&Kcb->RefCount);
382
383 /* Check if we still control the index */
384 if (Kcb->DelayedCloseIndex == 1)
385 {
386 /* Reset it */
387 Kcb->DelayedCloseIndex = 0;
388 }
389 else
390 {
391 /* Sanity check */
392 ASSERT((Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ||
393 (Kcb->DelayedCloseIndex == 0));
394 }
395 }
396 }
397 }
398
399 /* Increase the reference count */
400 if ((InterlockedIncrement((PLONG)&Kcb->RefCount) & 0xFFFF) == 0)
401 {
402 /* We've overflown to 64K references, bail out */
403 InterlockedDecrement((PLONG)&Kcb->RefCount);
404 return FALSE;
405 }
406
407 /* Check if this was the last close index */
408 if (!Kcb->DelayedCloseIndex)
409 {
410 /* Check if the KCB is locked in shared mode */
411 if (!CmpIsKcbLockedExclusive(Kcb))
412 {
413 /* Convert it to exclusive */
415 {
416 /* Go from shared to exclusive */
418 }
419 }
420
421 /* If we're still the last entry, remove us */
422 if (!Kcb->DelayedCloseIndex) CmpRemoveFromDelayedClose(Kcb);
423 }
424
425 /* Return success */
426 return TRUE;
427}

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

◆ CmpReleaseTwoKcbLockByKey()

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

Definition at line 2108 of file cmsysini.c.

2110{
2111 ULONG Index1, Index2;
2112
2113 /* Sanity check */
2115
2116 /* Get hash indexes */
2117 Index1 = GET_HASH_INDEX(ConvKey1);
2118 Index2 = GET_HASH_INDEX(ConvKey2);
2121
2122 /* See which one is highest */
2123 if (Index1 < Index2)
2124 {
2125 /* Grab them in the proper order */
2128 CmpReleaseKcbLockByKey(ConvKey2);
2129 CmpReleaseKcbLockByKey(ConvKey1);
2130 }
2131 else
2132 {
2133 /* Release the first one first, then the second */
2134 if (Index1 != Index2)
2135 {
2138 CmpReleaseKcbLockByKey(ConvKey1);
2139 }
2140 CmpReleaseKcbLockByKey(ConvKey2);
2141 }
2142}
#define GET_HASH_ENTRY(Table, ConvKey)
Definition: cm_x.h:26
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597

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

◆ CmpRemoveFromDelayedClose()

VOID NTAPI CmpRemoveFromDelayedClose ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 425 of file cmdelay.c.

426{
428 ULONG NewRefCount, OldRefCount;
429 PAGED_CODE();
430
431 /* Sanity checks */
433 if (Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ASSERT(FALSE);
434
435 /* Get the entry and lock the table */
436 Entry = Kcb->DelayCloseEntry;
437 ASSERT(Entry);
439
440 /* Remove the entry */
441 RemoveEntryList(&Entry->DelayedLRUList);
442
443 /* Release the lock */
445
446 /* Free the entry */
448
449 /* Reduce the number of elements */
451
452 /* Sanity check */
453 if (!Kcb->InDelayClose) ASSERT(FALSE);
454
455 /* Get the previous reference count */
456 OldRefCount = *(PLONG)&Kcb->InDelayClose;
457 ASSERT(OldRefCount == 1);
458
459 /* Write the new one */
460 NewRefCount = 0;
461 if (InterlockedCompareExchange((PLONG)&Kcb->InDelayClose,
462 NewRefCount,
463 OldRefCount) != OldRefCount)
464 {
465 /* Sanity check */
466 ASSERT(FALSE);
467 }
468
469 /* Remove the link to the entry */
470 Kcb->DelayCloseEntry = NULL;
471
472 /* Set new delay size and remove the delete flag */
473 Kcb->DelayedCloseIndex = CmpDelayedCloseSize;
474}
VOID NTAPI CmpFreeDelayItem(PVOID Entry)
Definition: cmalloc.c:267

Referenced by CmpEnumerateOpenSubKeys(), CmpLookInCache(), and CmpReferenceKeyControlBlock().

◆ CmpRemoveFromHiveFileList()

VOID NTAPI CmpRemoveFromHiveFileList ( IN PCMHIVE  Hive)

Definition at line 254 of file cmhvlist.c.

255{
259 UNICODE_STRING HivePath;
260
261 /* Open the hive list key */
265 NULL,
266 NULL);
267 Status = ZwOpenKey(&KeyHandle,
270 if (!NT_SUCCESS(Status))
271 {
272 /* Fail */
273 DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status = 0x%08lx\n", Status);
274 return;
275 }
276
277 /* Get the hive path name */
278 CmpGetHiveName(Hive, &HivePath);
279
280 /* Delete the hive path name from the list */
281 ZwDeleteValueKey(KeyHandle, &HivePath);
282
283 /* Cleanup allocation and handle */
286}
NTSYSAPI NTSTATUS NTAPI ZwDeleteValueKey(__in IN HANDLE Key, __in IN PUNICODE_STRING ValueName)

Referenced by CmUnloadKey().

◆ CmpRemoveKeyControlBlock()

VOID NTAPI CmpRemoveKeyControlBlock ( IN PCM_KEY_CONTROL_BLOCK  Kcb)

Definition at line 306 of file cmkcbncb.c.

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

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

◆ CmpReportNotify()

VOID NTAPI CmpReportNotify ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN PHHIVE  Hive,
IN HCELL_INDEX  Cell,
IN ULONG  Filter 
)

Definition at line 19 of file cmnotify.c.

23{
24 /* FIXME: TODO */
25 return;
26}

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmpDoCreateChild(), and CmSetValueKey().

◆ CmpSaveBootControlSet()

NTSTATUS NTAPI CmpSaveBootControlSet ( IN USHORT  ControlSet)

Definition at line 267 of file cmcontrl.c.

268{
269 DPRINT1("CmpSaveBootControlSet(%lu)\n", ControlSet);
270 return STATUS_SUCCESS;
271}

Referenced by NtInitializeRegistry().

◆ CmpSecurityMethod()

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 
)

◆ CmpSetGlobalQuotaAllowed()

VOID NTAPI CmpSetGlobalQuotaAllowed ( VOID  )

Definition at line 22 of file cmquota.c.

23{
24 /* Set flag ON if quota enabled */
26}
BOOLEAN CmpGlobalQuota
Definition: cmquota.c:15
BOOLEAN CmpGlobalQuotaAllowed
Definition: cmquota.c:16

Referenced by CmLoadKey().

◆ CmpSetVersionData()

VOID NTAPI CmpSetVersionData ( VOID  )

Definition at line 2182 of file cmsysini.c.

2183{
2189 ANSI_STRING TempString;
2190 HANDLE SoftwareKeyHandle = NULL;
2191 HANDLE MicrosoftKeyHandle = NULL;
2192 HANDLE WindowsNtKeyHandle = NULL;
2193 HANDLE CurrentVersionKeyHandle = NULL;
2194 WCHAR Buffer[128]; // Buffer large enough to contain a full ULONG in decimal
2195 // representation, and the full 'CurrentType' string.
2196
2197 /*
2198 * Open the 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' key
2199 * (create the intermediate subkeys if needed).
2200 */
2201
2202 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SOFTWARE");
2204 &KeyName,
2206 NULL,
2207 NULL);
2208 Status = NtCreateKey(&SoftwareKeyHandle,
2211 0,
2212 NULL,
2213 0,
2214 NULL);
2215 if (!NT_SUCCESS(Status))
2216 {
2217 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2218 return;
2219 }
2220
2221 RtlInitUnicodeString(&KeyName, L"Microsoft");
2223 &KeyName,
2225 SoftwareKeyHandle,
2226 NULL);
2227 Status = NtCreateKey(&MicrosoftKeyHandle,
2230 0,
2231 NULL,
2232 0,
2233 NULL);
2234 if (!NT_SUCCESS(Status))
2235 {
2236 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2237 goto Quit;
2238 }
2239
2240 RtlInitUnicodeString(&KeyName, L"Windows NT");
2242 &KeyName,
2244 MicrosoftKeyHandle,
2245 NULL);
2246 Status = NtCreateKey(&WindowsNtKeyHandle,
2249 0,
2250 NULL,
2251 0,
2252 NULL);
2253 if (!NT_SUCCESS(Status))
2254 {
2255 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2256 goto Quit;
2257 }
2258
2259 RtlInitUnicodeString(&KeyName, L"CurrentVersion");
2261 &KeyName,
2263 WindowsNtKeyHandle,
2264 NULL);
2265 Status = NtCreateKey(&CurrentVersionKeyHandle,
2268 0,
2269 NULL,
2270 0,
2271 NULL);
2272 if (!NT_SUCCESS(Status))
2273 {
2274 DPRINT1("Failed to create key %wZ (Status: %08lx)\n", &KeyName, Status);
2275 goto Quit;
2276 }
2277
2278 /* Set the 'CurrentVersion' value */
2279 RtlInitUnicodeString(&ValueName, L"CurrentVersion");
2280 NtSetValueKey(CurrentVersionKeyHandle,
2281 &ValueName,
2282 0,
2283 REG_SZ,
2285 CmVersionString.Length + sizeof(WCHAR));
2286
2287 /* Set the 'CurrentBuildNumber' value */
2288 RtlInitUnicodeString(&ValueName, L"CurrentBuildNumber");
2289 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2291 NtSetValueKey(CurrentVersionKeyHandle,
2292 &ValueName,
2293 0,
2294 REG_SZ,
2295 ValueData.Buffer,
2296 ValueData.Length + sizeof(WCHAR));
2297
2298 /* Set the 'BuildLab' value */
2299 RtlInitUnicodeString(&ValueName, L"BuildLab");
2300 RtlInitAnsiString(&TempString, NtBuildLab);
2302 if (NT_SUCCESS(Status))
2303 {
2304 NtSetValueKey(CurrentVersionKeyHandle,
2305 &ValueName,
2306 0,
2307 REG_SZ,
2308 ValueData.Buffer,
2309 ValueData.Length + sizeof(WCHAR));
2310 }
2311
2312 /* Set the 'CurrentType' value */
2313 RtlInitUnicodeString(&ValueName, L"CurrentType");
2315 L"%s %s",
2316#ifdef CONFIG_SMP
2317 L"Multiprocessor"
2318#else
2319 L"Uniprocessor"
2320#endif
2321 ,
2322#if (DBG == 1)
2323 L"Checked"
2324#else
2325 L"Free"
2326#endif
2327 );
2329 NtSetValueKey(CurrentVersionKeyHandle,
2330 &ValueName,
2331 0,
2332 REG_SZ,
2333 ValueData.Buffer,
2334 ValueData.Length + sizeof(WCHAR));
2335
2336 /* Set the 'CSDVersion' value */
2337 RtlInitUnicodeString(&ValueName, L"CSDVersion");
2338 if (CmCSDVersionString.Length != 0)
2339 {
2340 NtSetValueKey(CurrentVersionKeyHandle,
2341 &ValueName,
2342 0,
2343 REG_SZ,
2345 CmCSDVersionString.Length + sizeof(WCHAR));
2346 }
2347 else
2348 {
2349 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2350 }
2351
2352 /* Set the 'CSDBuildNumber' value */
2353 RtlInitUnicodeString(&ValueName, L"CSDBuildNumber");
2354 if (CmNtSpBuildNumber != 0)
2355 {
2356 RtlInitEmptyUnicodeString(&ValueData, Buffer, sizeof(Buffer));
2358 NtSetValueKey(CurrentVersionKeyHandle,
2359 &ValueName,
2360 0,
2361 REG_SZ,
2362 ValueData.Buffer,
2363 ValueData.Length + sizeof(WCHAR));
2364 }
2365 else
2366 {
2367 NtDeleteValueKey(CurrentVersionKeyHandle, &ValueName);
2368 }
2369
2370 /* Set the 'SystemRoot' value */
2371 RtlInitUnicodeString(&ValueName, L"SystemRoot");
2372 NtSetValueKey(CurrentVersionKeyHandle,
2373 &ValueName,
2374 0,
2375 REG_SZ,
2377 NtSystemRoot.Length + sizeof(WCHAR));
2378
2379Quit:
2380 /* Close the keys */
2381 if (CurrentVersionKeyHandle != NULL)
2382 NtClose(CurrentVersionKeyHandle);
2383
2384 if (WindowsNtKeyHandle != NULL)
2385 NtClose(WindowsNtKeyHandle);
2386
2387 if (MicrosoftKeyHandle != NULL)
2388 NtClose(MicrosoftKeyHandle);
2389
2390 if (SoftwareKeyHandle != NULL)
2391 NtClose(SoftwareKeyHandle);
2392}
#define DBG(x)
Definition: moztest.c:12
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:1014
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString(ULONG Value, ULONG Base, PUNICODE_STRING String)
#define KEY_SET_VALUE
Definition: nt_native.h:1017
UNICODE_STRING NtSystemRoot
Definition: init.c:76
CHAR NtBuildLab[]
Definition: init.c:64
UNICODE_STRING CmVersionString
Definition: init.c:61
ULONG CmNtSpBuildNumber
Definition: init.c:58
UNICODE_STRING CmCSDVersionString
Definition: init.c:62
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
ULONG NtBuildNumber
Definition: init.c:50

Referenced by NtInitializeRegistry().

◆ CmpShutdownWorkers()

VOID NTAPI CmpShutdownWorkers ( VOID  )

Definition at line 437 of file cmlazy.c.

438{
439 /* Stop lazy flushing */
440 PAGED_CODE();
442}
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206

Referenced by CmShutdownSystem().

◆ CmpTestHiveFlusherLockExclusive()

BOOLEAN NTAPI CmpTestHiveFlusherLockExclusive ( IN PCMHIVE  Hive)

Definition at line 2048 of file cmsysini.c.

2049{
2050 /* Test the lock */
2051 return !ExIsResourceAcquiredExclusiveLite(Hive->FlusherLock) ? FALSE : TRUE;
2052}

◆ CmpTestHiveFlusherLockShared()

BOOLEAN NTAPI CmpTestHiveFlusherLockShared ( IN PCMHIVE  Hive)

Definition at line 2040 of file cmsysini.c.

2041{
2042 /* Test the lock */
2043 return !ExIsResourceAcquiredSharedLite(Hive->FlusherLock) ? FALSE : TRUE;
2044}
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663

◆ CmpTestRegistryLock()

BOOLEAN NTAPI CmpTestRegistryLock ( VOID  )

Definition at line 1990 of file cmsysini.c.

1991{
1992 /* Test the lock */
1994}

◆ CmpTestRegistryLockExclusive()

BOOLEAN NTAPI CmpTestRegistryLockExclusive ( VOID  )

Definition at line 1998 of file cmsysini.c.

1999{
2000 /* Test the lock */
2002}

Referenced by CmFlushKey(), and CmpReleaseTwoKcbLockByKey().

◆ CmpUnlockHiveFlusher()

VOID NTAPI CmpUnlockHiveFlusher ( IN PCMHIVE  Hive)

Definition at line 2028 of file cmsysini.c.

2029{
2030 /* Sanity check */
2033
2034 /* Release the lock */
2035 ExReleaseResourceLite(Hive->FlusherLock);
2036}
#define CMP_ASSERT_FLUSH_LOCK(h)
Definition: cm_x.h:282
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822

Referenced by CmDeleteKey(), CmDeleteValueKey(), CmFlushKey(), CmLoadKey(), CmpCreateLinkNode(), CmpDoCreate(), CmpDoFlushAll(), CmpUnlinkHiveFromMaster(), and CmSetValueKey().

◆ CmpUnLockKcbArray()

VOID CmpUnLockKcbArray ( _In_ PULONG  KcbArray)

Unlocks a number of KCBs provided by a KCB array.

Parameters
[in]KcbArrayA pointer to an array of KCBs to be unlocked.

Definition at line 1145 of file cmkcbncb.c.

1147{
1148 ULONG i;
1149
1150 /* Release the locked KCBs in reverse order */
1151 for (i = KcbArray[0]; i > 0; i--)
1152 {
1153 CmpReleaseKcbLockByIndex(KcbArray[i]);
1154 }
1155}
FORCEINLINE VOID CmpReleaseKcbLockByIndex(ULONG Index)
Definition: cm_x.h:174

Referenced by CmpDoOpen(), CmpLookInCache(), and CmpParseKey().

◆ CmpUnlockRegistry()

VOID NTAPI CmpUnlockRegistry ( VOID  )

Definition at line 2056 of file cmsysini.c.

2057{
2058 /* Sanity check */
2060
2061 /* Check if we should flush the registry */
2063 {
2064 /* The registry should be exclusively locked for this */
2066
2067 /* Flush the registry */
2070 }
2071
2072 /* Release the lock and leave the critical region */
2075}
BOOLEAN CmpFlushOnLockRelease
Definition: cmsysini.c:25
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119

Referenced by _Function_class_(), CmDeleteKey(), CmDeleteValueKey(), CmEnumerateKey(), CmEnumerateValueKey(), CmGetSystemDriverList(), CmLoadKey(), CmpDeleteKeyObject(), CmpParseKey(), CmpQueryKeyName(), CmpSecurityMethod(), CmQueryKey(), CmQueryValueKey(), CmSaveKey(), CmSaveMergedKeys(), CmSetValueKey(), CmShutdownSystem(), CmUnloadKey(), NtFlushKey(), NtInitializeRegistry(), NtQueryOpenSubKeys(), and NtUnloadKey2().

◆ CmQueryKey()

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

◆ CmQueryValueKey()

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 
)

Definition at line 1074 of file cmapi.c.

1080{
1083 ULONG Index;
1084 BOOLEAN ValueCached = FALSE;
1085 PCM_CACHED_VALUE *CachedValue;
1086 HCELL_INDEX CellToRelease;
1088 PHHIVE Hive;
1089 PAGED_CODE();
1090
1091 /* Acquire hive lock */
1093
1094 /* Lock the KCB shared */
1096
1097 /* Don't touch deleted keys */
1098DoAgain:
1099 if (Kcb->Delete)
1100 {
1101 /* Undo everything */
1102 CmpReleaseKcbLock(Kcb);
1104 return STATUS_KEY_DELETED;
1105 }
1106
1107 /* We don't deal with this yet */
1108 if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
1109 {
1110 /* Shouldn't happen */
1111 ASSERT(FALSE);
1112 }
1113
1114 /* Get the hive */
1115 Hive = Kcb->KeyHive;
1116
1117 /* Find the key value */
1119 &ValueName,
1120 &CachedValue,
1121 &Index,
1122 &ValueData,
1123 &ValueCached,
1124 &CellToRelease);
1126 {
1127 /* Check if we need an exclusive lock */
1128 ASSERT(CellToRelease == HCELL_NIL);
1129 ASSERT(ValueData == NULL);
1130
1131 /* Try with exclusive KCB lock */
1133 goto DoAgain;
1134 }
1135
1136 if (Result == SearchSuccess)
1137 {
1138 /* Sanity check */
1139 ASSERT(ValueData != NULL);
1140
1141 /* User data, protect against exceptions */
1142 _SEH2_TRY
1143 {
1144 /* Query the information requested */
1146 CachedValue,
1147 ValueData,
1148 ValueCached,
1150 KeyValueInformation,
1151 Length,
1153 &Status);
1155 {
1156 /* Release the value cell */
1157 if (CellToRelease != HCELL_NIL)
1158 {
1159 HvReleaseCell(Hive, CellToRelease);
1160 CellToRelease = HCELL_NIL;
1161 }
1162
1163 /* Try with exclusive KCB lock */
1165 _SEH2_YIELD(goto DoAgain);
1166 }
1167 }
1169 {
1171 }
1172 _SEH2_END;
1173 }
1174 else
1175 {
1176 /* Failed to find the value */
1178 }
1179
1180 /* If we have a cell to release, do so */
1181 if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
1182
1183 /* Release locks */
1184 CmpReleaseKcbLock(Kcb);
1186 return Status;
1187}

Referenced by NtQueryValueKey().

◆ CmSaveKey()

NTSTATUS NTAPI CmSaveKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN HANDLE  FileHandle,
IN ULONG  Flags 
)

Definition at line 2661 of file cmapi.c.

2664{
2665#if DBG
2666 CM_CHECK_REGISTRY_STATUS CheckStatus;
2667 PCMHIVE HiveToValidate = NULL;
2668#endif
2670 PCMHIVE KeyHive = NULL;
2671 PAGED_CODE();
2672
2673 DPRINT("CmSaveKey(0x%08X, 0x%08X, %lu)\n", Kcb, FileHandle, Flags);
2674
2675 /* Lock the registry and KCB */
2678
2679#if DBG
2680 /* Get the hive for validation */
2681 HiveToValidate = (PCMHIVE)Kcb->KeyHive;
2682#endif
2683
2684 if (Kcb->Delete)
2685 {
2686 /* The source key has been deleted, do nothing */
2688 goto Cleanup;
2689 }
2690
2691 if (Kcb->KeyHive == &CmiVolatileHive->Hive)
2692 {
2693 /* Keys that are directly in the master hive can't be saved */
2695 goto Cleanup;
2696 }
2697
2698#if DBG
2699 /* Make sure this control block has a sane hive */
2701 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2702#endif
2703
2704 /* Create a new hive that will hold the key */
2705 Status = CmpInitializeHive(&KeyHive,
2709 NULL,
2710 NULL,
2711 NULL,
2712 NULL,
2713 NULL,
2714 NULL,
2716 if (!NT_SUCCESS(Status)) goto Cleanup;
2717
2718 /* Copy the key recursively into the new hive */
2719 Status = CmpDeepCopyKey(Kcb->KeyHive,
2720 Kcb->KeyCell,
2721 &KeyHive->Hive,
2722 Stable,
2723 &KeyHive->Hive.BaseBlock->RootCell);
2724 if (!NT_SUCCESS(Status)) goto Cleanup;
2725
2726 /* Set the primary handle of the hive */
2728
2729 /* Dump the hive into the file */
2730 HvWriteHive(&KeyHive->Hive);
2731
2732Cleanup:
2733
2734 /* Free the hive */
2735 if (KeyHive) CmpDestroyHive(KeyHive);
2736
2737#if DBG
2738 if (NT_SUCCESS(Status))
2739 {
2740 /* Before we say goodbye, make sure the hive is still OK */
2742 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2743 }
2744#endif
2745
2746 /* Release the locks */
2747 CmpReleaseKcbLock(Kcb);
2749
2750 return Status;
2751}
NTSTATUS NTAPI CmpDeepCopyKey(IN PHHIVE SourceHive, IN HCELL_INDEX SrcKeyCell, IN PHHIVE DestinationHive, IN HSTORAGE_TYPE StorageType, OUT PHCELL_INDEX DestKeyCell OPTIONAL)
Definition: cmapi.c:2644
BOOLEAN CMAPI HvWriteHive(PHHIVE RegistryHive)
HCELL_INDEX RootCell
Definition: hivedata.h:168
PHBASE_BLOCK BaseBlock
Definition: hivedata.h:328

Referenced by NtSaveKeyEx().

◆ CmSaveMergedKeys()

NTSTATUS NTAPI CmSaveMergedKeys ( IN PCM_KEY_CONTROL_BLOCK  HighKcb,
IN PCM_KEY_CONTROL_BLOCK  LowKcb,
IN HANDLE  FileHandle 
)

Definition at line 2755 of file cmapi.c.

2758{
2759#if DBG
2760 CM_CHECK_REGISTRY_STATUS CheckStatus;
2761 PCMHIVE LowHiveToValidate = NULL;
2762 PCMHIVE HighHiveToValidate = NULL;
2763#endif
2764 PCMHIVE KeyHive = NULL;
2766
2767 PAGED_CODE();
2768
2769 DPRINT("CmSaveKey(%p, %p, %p)\n", HighKcb, LowKcb, FileHandle);
2770
2771 /* Lock the registry and the KCBs */
2773 CmpAcquireKcbLockShared(HighKcb);
2775
2776#if DBG
2777 /* Get the high and low hives for validation */
2778 HighHiveToValidate = (PCMHIVE)HighKcb->KeyHive;
2779 LowHiveToValidate = (PCMHIVE)LowKcb->KeyHive;
2780#endif
2781
2782 if (LowKcb->Delete || HighKcb->Delete)
2783 {
2784 /* The source key has been deleted, do nothing */
2786 goto done;
2787 }
2788
2789#if DBG
2790 /* Make sure that both the high and low precedence hives are OK */
2792 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2794 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2795#endif
2796
2797 /* Create a new hive that will hold the key */
2798 Status = CmpInitializeHive(&KeyHive,
2802 NULL,
2803 NULL,
2804 NULL,
2805 NULL,
2806 NULL,
2807 NULL,
2809 if (!NT_SUCCESS(Status))
2810 goto done;
2811
2812 /* Copy the low precedence key recursively into the new hive */
2813 Status = CmpDeepCopyKey(LowKcb->KeyHive,
2814 LowKcb->KeyCell,
2815 &KeyHive->Hive,
2816 Stable,
2817 &KeyHive->Hive.BaseBlock->RootCell);
2818 if (!NT_SUCCESS(Status))
2819 goto done;
2820
2821 /* Copy the high precedence key recursively into the new hive */
2822 Status = CmpDeepCopyKey(HighKcb->KeyHive,
2823 HighKcb->KeyCell,
2824 &KeyHive->Hive,
2825 Stable,
2826 &KeyHive->Hive.BaseBlock->RootCell);
2827 if (!NT_SUCCESS(Status))
2828 goto done;
2829
2830 /* Set the primary handle of the hive */
2832
2833 /* Dump the hive into the file */
2834 HvWriteHive(&KeyHive->Hive);
2835
2836done:
2837 /* Free the hive */
2838 if (KeyHive)
2839 CmpDestroyHive(KeyHive);
2840
2841#if DBG
2842 if (NT_SUCCESS(Status))
2843 {
2844 /* Check those hives again before we say goodbye */
2846 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2848 ASSERT(CM_CHECK_REGISTRY_SUCCESS(CheckStatus));
2849 }
2850#endif
2851
2852 /* Release the locks */
2853 CmpReleaseKcbLock(LowKcb);
2854 CmpReleaseKcbLock(HighKcb);
2856
2857 return Status;
2858}

Referenced by NtSaveMergedKeys().

◆ CmSetLazyFlushState()

VOID NTAPI CmSetLazyFlushState ( IN BOOLEAN  Enable)

Definition at line 446 of file cmlazy.c.

447{
448 /* Set state for lazy flusher */
450}
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142

Referenced by NtSetSystemPowerState().

◆ CmSetValueKey()

NTSTATUS NTAPI CmSetValueKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN PUNICODE_STRING  ValueName,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize 
)

Definition at line 643 of file cmapi.c.

648{
649 PHHIVE Hive = NULL;
652 HCELL_INDEX CurrentChild, Cell;
655 ULONG Count, ChildIndex, SmallData, Storage;
656 VALUE_SEARCH_RETURN_TYPE SearchResult;
657 BOOLEAN FirstTry = TRUE, FlusherLocked = FALSE;
658 HCELL_INDEX ParentCell = HCELL_NIL, ChildCell = HCELL_NIL;
659
660 /* Acquire hive and KCB lock */
663
664 /* Sanity check */
665 ASSERT(sizeof(ULONG) == CM_KEY_VALUE_SMALL);
666
667 /* Don't touch deleted KCBs */
668DoAgain:
669 if (Kcb->Delete)
670 {
671 /* Fail */
673 goto Quickie;
674 }
675
676 /* Don't let anyone mess with symlinks */
677 if ((Kcb->Flags & KEY_SYM_LINK) &&
678 ((Type != REG_LINK) ||
679 !(ValueName) ||
681 {
682 /* Invalid modification of a symlink key */
684 goto Quickie;
685 }
686
687 /* Check if this is the first attempt */
688 if (FirstTry)
689 {
690 /* Search for the value in the cache */
691 SearchResult = CmpCompareNewValueDataAgainstKCBCache(Kcb,
692 ValueName,
693 Type,
694 Data,
695 DataLength);
696 if (SearchResult == SearchNeedExclusiveLock)
697 {
698 /* Try again with the exclusive lock */
700 goto DoAgain;
701 }
702 else if (SearchResult == SearchSuccess)
703 {
704 /* We don't actually need to do anything! */
706 goto Quickie;
707 }
708
709 /* We need the exclusive KCB lock now */
710 if (!CmpIsKcbLockedExclusive(Kcb) &&
712 {
713 /* Acquire exclusive lock */
715 }
716
717 /* Cache lookup failed, so don't try it next time */
718 FirstTry = FALSE;
719
720 /* Now grab the flush lock since the key will be modified */
721 ASSERT(FlusherLocked == FALSE);
722 CmpLockHiveFlusherShared((PCMHIVE)Kcb->KeyHive);
723 FlusherLocked = TRUE;
724 goto DoAgain;
725 }
726 else
727 {
728 /* Get pointer to key cell */
729 Hive = Kcb->KeyHive;
730 Cell = Kcb->KeyCell;
731
732 /* Get the parent */
733 Parent = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
734 ASSERT(Parent);
735 ParentCell = Cell;
736
737 /* Prepare to scan the key node */
738 Count = Parent->ValueList.Count;
739 Found = FALSE;
740 if (Count > 0)
741 {
742 /* Try to find the existing name */
744 &Parent->ValueList,
745 ValueName,
746 &ChildIndex,
747 &CurrentChild);
748 if (!Result)
749 {
750 /* Fail */
752 goto Quickie;
753 }
754
755 /* Check if we found something */
756 if (CurrentChild != HCELL_NIL)
757 {
758 /* Release existing child */
759 if (ChildCell != HCELL_NIL)
760 {
761 HvReleaseCell(Hive, ChildCell);
762 ChildCell = HCELL_NIL;
763 }
764
765 /* Get its value */
766 Value = (PCM_KEY_VALUE)HvGetCell(Hive, CurrentChild);
767 if (!Value)
768 {
769 /* Fail */
771 goto Quickie;
772 }
773
774 /* Remember that we found it */
775 ChildCell = CurrentChild;
776 Found = TRUE;
777 }
778 }
779 else
780 {
781 /* No child list, we'll need to add it */
782 ChildIndex = 0;
783 }
784 }
785
786 /* Should only get here on the second pass */
788
789 /* The KCB must be locked exclusive at this point */
791
792 /* Mark the cell dirty */
793 if (!HvMarkCellDirty(Hive, Cell, FALSE))
794 {
795 /* Not enough log space, fail */
797 goto Quickie;
798 }
799
800 /* Get the storage type */
801 Storage = HvGetCellType(Cell);
802
803 /* Check if this is small data */
804 SmallData = 0;
805 if ((DataLength <= CM_KEY_VALUE_SMALL) && (DataLength > 0))
806 {
807 /* Need SEH because user data may be invalid */
809 {
810 /* Copy it */
811 RtlCopyMemory(&SmallData, Data, DataLength);
812 }
814 {
815 /* Return failure code */
817 _SEH2_YIELD(goto Quickie);
818 }
819 _SEH2_END;
820 }
821
822 /* Check if we didn't find a matching key */
823 if (!Found)
824 {
825 /* Call the internal routine */
827 Parent,
828 ValueName,
829 ChildIndex,
830 Type,
831 Data,
833 Storage,
834 SmallData);
835 }
836 else
837 {
838 /* Call the internal routine */
840 CurrentChild,
841 Value,
842 Type,
843 Data,
845 Storage,
846 SmallData);
847 }
848
849 /* Check for success */
850 if (NT_SUCCESS(Status))
851 {
852 /* Check if the maximum value name length changed */
853 ASSERT(Parent->MaxValueNameLen == Kcb->KcbMaxValueNameLen);
854 if (Parent->MaxValueNameLen < ValueName->Length)
855 {
856 /* Set the new values */
857 Parent->MaxValueNameLen = ValueName->Length;
858 Kcb->KcbMaxValueNameLen = ValueName->Length;
859 }
860
861 /* Check if the maximum data length changed */
862 ASSERT(Parent->MaxValueDataLen == Kcb->KcbMaxValueDataLen);
863 if (Parent->MaxValueDataLen < DataLength)
864 {
865 /* Update it */
866 Parent->MaxValueDataLen = DataLength;
867 Kcb->KcbMaxValueDataLen = Parent->MaxValueDataLen;
868 }
869
870 /* Save the write time */
871 KeQuerySystemTime(&Parent->LastWriteTime);
872 Kcb->KcbLastWriteTime = Parent->LastWriteTime;
873
874 /* Check if the cell is cached */
875 if (Found && CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))
876 {
877 /* Shouldn't happen */
878 ASSERT(FALSE);
879 }
880 else
881 {
882 /* Cleanup the value cache */
884
885 /* Sanity checks */
886 ASSERT(!CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList));
887 ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
888
889 /* Set the value cache */
890 Kcb->ValueCache.Count = Parent->ValueList.Count;
891 Kcb->ValueCache.ValueList = Parent->ValueList.List;
892 }
893
894 /* Notify registered callbacks */
895 CmpReportNotify(Kcb,
896 Hive,
897 Kcb->KeyCell,
899 }
900
901 /* Release the cells */
902Quickie:
903 if ((ParentCell != HCELL_NIL) && Hive) HvReleaseCell(Hive, ParentCell);
904 if ((ChildCell != HCELL_NIL) && Hive) HvReleaseCell(Hive, ChildCell);
905
906 /* Release the locks */
907 if (FlusherLocked) CmpUnlockHiveFlusher((PCMHIVE)Hive);
910 return Status;
911}
return Found
Definition: dirsup.c:1270
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
NTSTATUS NTAPI CmpSetValueKeyExisting(IN PHHIVE Hive, IN HCELL_INDEX OldChild, IN PCM_KEY_VALUE Value, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG TempData)
Definition: cmapi.c:270
NTSTATUS NTAPI CmpSetValueKeyNew(IN PHHIVE Hive, IN PCM_KEY_NODE Parent, IN PUNICODE_STRING ValueName, IN ULONG Index, IN ULONG Type, IN PVOID Data, IN ULONG DataSize, IN ULONG StorageType, IN ULONG SmallData)
Definition: cmapi.c:146
UNICODE_STRING CmSymbolicLinkValueName
Definition: cmdata.c:52
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: cmvalche.c:700
static IStorage Storage
Definition: ole2.c:3548
int Count
Definition: noreturn.cpp:7
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define REG_LINK
Definition: nt_native.h:1500
@ FirstTry
Definition: copy.c:25
UINT32 Length
Definition: actbl.h:109

Referenced by NtSetValueKey().

◆ CmShutdownSystem()

VOID NTAPI CmShutdownSystem ( VOID  )

Definition at line 2146 of file cmsysini.c.

2147{
2148 PLIST_ENTRY ListEntry;
2149 PCMHIVE Hive;
2150
2151 /* Kill the workers */
2153
2154 /* Flush all hives */
2157
2158 /* Close all hive files */
2159 ListEntry = CmpHiveListHead.Flink;
2160 while (ListEntry != &CmpHiveListHead)
2161 {
2162 Hive = CONTAINING_RECORD(ListEntry, CMHIVE, HiveList);
2163
2164 CmpCloseHiveFiles(Hive);
2165
2166 ListEntry = ListEntry->Flink;
2167 }
2168
2169 /*
2170 * As we flushed all the hives on the disk,
2171 * tell the system we do not want any further
2172 * registry flushing or syncing at this point
2173 * since we are shutting down the registry anyway.
2174 */
2176
2178}
VOID NTAPI CmpShutdownWorkers(VOID)
Definition: cmlazy.c:437
BOOLEAN CmFirstTime
Definition: ntapi.c:17

Referenced by PopGracefulShutdown().

◆ CmUnloadKey()

NTSTATUS NTAPI CmUnloadKey ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
IN ULONG  Flags 
)

NOTE: The following code is mostly equivalent to what we "call" CmpDestroyHive()

Definition at line 2209 of file cmapi.c.

2211{
2212 PHHIVE Hive;
2213 PCMHIVE CmHive;
2214 HCELL_INDEX Cell;
2215
2216 DPRINT("CmUnloadKey(%p, %lx)\n", Kcb, Flags);
2217
2218 /* Get the hive */
2219 Hive = Kcb->KeyHive;
2220 Cell = Kcb->KeyCell;
2221 CmHive = (PCMHIVE)Hive;
2222
2223 /* Fail if the key is not a hive root key */
2224 if (Cell != Hive->BaseBlock->RootCell)
2225 {
2226 DPRINT1("Key is not a hive root key!\n");
2228 }
2229
2230 /* Fail if we try to unload the master hive */
2231 if (CmHive == CmiVolatileHive)
2232 {
2233 DPRINT1("Do not try to unload the master hive!\n");
2235 }
2236
2237 /* Mark this hive as being unloaded */
2239
2240 /* Search for any opened keys in this hive, and take an appropriate action */
2241 if (Kcb->RefCount > 1)
2242 {
2243 if (Flags != REG_FORCE_UNLOAD)
2244 {
2245 if (CmpEnumerateOpenSubKeys(Kcb, FALSE, TRUE, FALSE) != 0)
2246 {
2247 /* There are open subkeys but we don't force hive unloading, fail */
2248 Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2249 return STATUS_CANNOT_DELETE;
2250 }
2251 }
2252 else
2253 {
2254 if (CmpEnumerateOpenSubKeys(Kcb, TRUE, TRUE, TRUE) != 0)
2255 {
2256 /* There are open subkeys that we cannot force to unload, fail */
2257 Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2258 return STATUS_CANNOT_DELETE;
2259 }
2260 }
2261 }
2262
2263 /* Set the loading flag */
2264 CmHive->HiveIsLoading = TRUE;
2265
2266 /* Flush the hive */
2267 CmFlushKey(Kcb, TRUE);
2268
2269 /* Unlink the hive from the master hive */
2270 if (!CmpUnlinkHiveFromMaster(CmHive, Cell))
2271 {
2272 DPRINT("CmpUnlinkHiveFromMaster() failed!\n");
2273
2274 /* Remove the unloading flag */
2275 Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
2276
2277 /* Reset the loading flag */
2278 CmHive->HiveIsLoading = FALSE;
2279
2280 /* Return failure */
2282 }
2283
2284 /* Flush any notifications if we force hive unloading */
2285 if (Flags == REG_FORCE_UNLOAD)
2286 CmpFlushNotifiesOnKeyBodyList(Kcb, TRUE); // Lock is already held
2287
2288 /* Clean up information we have on the subkey */
2289 CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
2290
2291 /* Set the KCB in delete mode and remove it */
2292 Kcb->Delete = TRUE;
2294
2295 if (Flags != REG_FORCE_UNLOAD)
2296 {
2297 /* Release the KCB locks */
2298 CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
2299
2300 /* Release the hive loading lock */
2302 }
2303
2304 /* Release hive lock */
2306
2307 /* Close file handles */
2308 CmpCloseHiveFiles(CmHive);
2309
2310 /* Remove the hive from the hive file list */
2312
2317 /* Destroy the security descriptor cache */
2319
2320 /* Destroy the view list */
2321 CmpDestroyHiveViewList(CmHive);
2322
2323 /* Delete the flusher lock */
2326
2327 /* Delete the view lock */
2329
2330 /* Free the hive storage */
2331 HvFree(Hive);
2332
2333 /* Free the hive */
2334 CmpFree(CmHive, TAG_CM);
2335
2336 return STATUS_SUCCESS;
2337}
#define REG_FORCE_UNLOAD
static BOOLEAN NTAPI CmpUnlinkHiveFromMaster(IN PCMHIVE CmHive, IN HCELL_INDEX Cell)
Definition: cmapi.c:2169
ULONG NTAPI CmpEnumerateOpenSubKeys(_In_ PCM_KEY_CONTROL_BLOCK RootKcb, _In_ BOOLEAN LockHeldExclusively, _In_ BOOLEAN RemoveEmptyCacheEntries, _In_ BOOLEAN DereferenceOpenedEntries)
Definition: cmapi.c:2341
NTSTATUS NTAPI CmFlushKey(IN PCM_KEY_CONTROL_BLOCK Kcb, IN BOOLEAN ExclusiveLock)
Definition: cmapi.c:1937
VOID NTAPI CmpRemoveFromHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:254
FORCEINLINE VOID ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
Definition: ex.h:1252

Referenced by NtUnloadKey2().

◆ DelistKeyBodyFromKCB()

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

Definition at line 1100 of file cmkcbncb.c.

1102{
1103 ULONG i;
1104
1105 /* Sanity check */
1106 ASSERT(KeyBody->KeyControlBlock != NULL);
1107
1108 /* Check if we can use the parent KCB array */
1109 for (i = 0; i < 4; i++)
1110 {
1111 /* Add it into the list */
1112 if (InterlockedCompareExchangePointer((PVOID*)&KeyBody->KeyControlBlock->
1113 KeyBodyArray[i],
1114 NULL,
1115 KeyBody) == KeyBody)
1116 {
1117 /* Removed */
1118 return;
1119 }
1120 }
1121
1122 /* Sanity checks */
1123 ASSERT(IsListEmpty(&KeyBody->KeyControlBlock->KeyBodyListHead) == FALSE);
1124 ASSERT(IsListEmpty(&KeyBody->KeyBodyList) == FALSE);
1125
1126 /* Lock the KCB */
1127 if (!LockHeld) CmpAcquireKcbLockExclusive(KeyBody->KeyControlBlock);
1128 CMP_ASSERT_KCB_LOCK(KeyBody->KeyControlBlock);
1129
1130 /* Remove the entry */
1131 RemoveEntryList(&KeyBody->KeyBodyList);
1132
1133 /* Unlock it it if we did a manual lock */
1134 if (!LockHeld) CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1135}
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129

Referenced by CmpDeleteKeyObject().

◆ EnlistKeyBodyWithKCB()

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

Definition at line 1042 of file cmkcbncb.c.

1044{
1045 ULONG i;
1046
1047 /* Sanity check */
1048 ASSERT(KeyBody->KeyControlBlock != NULL);
1049
1050 /* Initialize the list entry */
1051 InitializeListHead(&KeyBody->KeyBodyList);
1052
1053 /* Check if we can use the parent KCB array */
1054 for (i = 0; i < 4; i++)
1055 {
1056 /* Add it into the list */
1057 if (!InterlockedCompareExchangePointer((PVOID*)&KeyBody->KeyControlBlock->
1058 KeyBodyArray[i],
1059 KeyBody,
1060 NULL))
1061 {
1062 /* Added */
1063 return;
1064 }
1065 }
1066
1067 /* Array full, check if we need to unlock the KCB */
1069 {
1070 /* It's shared, so release the KCB shared lock */
1071 CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1073 }
1074
1075 /* Check if we need to lock the KCB */
1077 {
1078 /* Acquire the lock */
1079 CmpAcquireKcbLockExclusive(KeyBody->KeyControlBlock);
1080 }
1081
1082 /* Make sure we have the exclusive lock */
1083 CMP_ASSERT_KCB_LOCK(KeyBody->KeyControlBlock);
1084
1085 /* Do the insert */
1086 InsertTailList(&KeyBody->KeyControlBlock->KeyBodyListHead,
1087 &KeyBody->KeyBodyList);
1088
1089 /* Check if we did a manual lock */
1092 {
1093 /* Release the lock */
1094 CmpReleaseKcbLock(KeyBody->KeyControlBlock);
1095 }
1096}
#define CMP_ENLIST_KCB_LOCKED_SHARED
Definition: cm.h:95
#define CMP_ENLIST_KCB_LOCKED_EXCLUSIVE
Definition: cm.h:96

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

Variable Documentation

◆ CmClassName

UNICODE_STRING CmClassName[]
extern

◆ CmControlHive

CMHIVE CmControlHive
extern

Definition at line 34 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmControlVector

CM_SYSTEM_CONTROL_VECTOR CmControlVector[]
extern

Referenced by ExpInitializeExecutive().

◆ CmDefaultLanguageId

WCHAR CmDefaultLanguageId[]
extern

Definition at line 22 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmDefaultLanguageIdLength

ULONG CmDefaultLanguageIdLength
extern

Definition at line 23 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmDefaultLanguageIdType

ULONG CmDefaultLanguageIdType
extern

Definition at line 24 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmiKeyObjectListHead

LIST_ENTRY CmiKeyObjectListHead
extern

◆ CmInstallUILanguageId

WCHAR CmInstallUILanguageId[]
extern

Definition at line 26 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmInstallUILanguageIdLength

ULONG CmInstallUILanguageIdLength
extern

Definition at line 27 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmInstallUILanguageIdType

ULONG CmInstallUILanguageIdType
extern

Definition at line 28 of file cmdata.c.

Referenced by CmGetSystemControlValues().

◆ CmiVolatileHive

PCMHIVE CmiVolatileHive
extern

Definition at line 16 of file cmsysini.c.

◆ CmNtGlobalFlag

ULONG CmNtGlobalFlag
extern

Definition at line 19 of file cmdata.c.

Referenced by ExpInitializeExecutive().

◆ CmpBootType

ULONG CmpBootType
extern

Definition at line 62 of file cmdata.c.

◆ CmpCacheTable

◆ CmpConfigurationAreaSize

ULONG CmpConfigurationAreaSize
extern

◆ CmpConfigurationData

◆ CmpDelayedCloseIndex

ULONG CmpDelayedCloseIndex

Definition at line 1460 of file cm.h.

◆ CmpDelayedCloseSize

◆ CmpDelayedCloseTableLock

KGUARDED_MUTEX CmpDelayedCloseTableLock
extern

◆ CmpFlushOnLockRelease

BOOLEAN CmpFlushOnLockRelease
extern

Definition at line 25 of file cmsysini.c.

Referenced by CmpUnlockRegistry().

◆ CmpForceForceFlush

BOOLEAN CmpForceForceFlush
extern

Definition at line 22 of file cmlazy.c.

Referenced by _Function_class_(), and CmpDoFlushAll().

◆ CmpHashTableSize

ULONG CmpHashTableSize
extern

Definition at line 17 of file cmkcbncb.c.

Referenced by CmpEnumerateOpenSubKeys(), and CmpInitializeCache().

◆ CmpHiveListHead

LIST_ENTRY CmpHiveListHead
extern

◆ CmpHiveListHeadLock

EX_PUSH_LOCK CmpHiveListHeadLock
extern

◆ CmpHoldLazyFlush

◆ CmpKeyObjectType

POBJECT_TYPE CmpKeyObjectType
extern

◆ CmpLoadHiveLock

EX_PUSH_LOCK CmpLoadHiveLock

Definition at line 1424 of file cm.h.

◆ CmpLoadOptions

UNICODE_STRING CmpLoadOptions
extern

Definition at line 55 of file cmdata.c.

Referenced by CmInitSystem1(), CmpInitializeSystemHive(), and CmpSetSystemValues().

◆ CmpMachineHiveList

HIVE_LIST_ENTRY CmpMachineHiveList[]
extern

◆ CmpMiniNTBoot

BOOLEAN CmpMiniNTBoot
extern

Definition at line 60 of file cmdata.c.

Referenced by CmInitSystem1(), CmpCmdInit(), and CmpOpenHiveFiles().

◆ CmpMultifunctionTypes

CMP_MF_TYPE CmpMultifunctionTypes[]
extern

◆ CmpNameCacheTable

PCM_NAME_HASH_TABLE_ENTRY CmpNameCacheTable
extern

◆ CmpNoVolatileCreates

BOOLEAN CmpNoVolatileCreates
extern

Definition at line 34 of file cmsysini.c.

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

◆ CmpNoWrite

◆ CmpProfileLoaded

BOOLEAN CmpProfileLoaded
extern

Definition at line 33 of file cmsysini.c.

Referenced by CmLoadKey().

◆ CmpRegistryLock

◆ CmpRegistryRootHandle

HANDLE CmpRegistryRootHandle
extern

Definition at line 69 of file cmdata.c.

Referenced by CmpCreateRegistryRoot().

◆ CmpSelfHeal

BOOLEAN CmpSelfHeal
extern

Definition at line 64 of file cmdata.c.

◆ CmpShareSystemHives

◆ CmpSpecialBootCondition

BOOLEAN CmpSpecialBootCondition
extern

Definition at line 26 of file cmsysini.c.

Referenced by CmFlushKey(), and CmpInitializeHiveList().

◆ CmpSystemStartOptions

UNICODE_STRING CmpSystemStartOptions
extern

◆ CmpTraceLevel

ULONG CmpTraceLevel
extern

Definition at line 35 of file cmsysini.c.

◆ CmpTypeCount

ULONG CmpTypeCount[MaximumType+1]
extern

Definition at line 67 of file cmdata.c.

Referenced by CmpSetupConfigurationTree().

◆ CmpUnknownBusCount

USHORT CmpUnknownBusCount
extern

Definition at line 66 of file cmdata.c.

Referenced by CmpSetupConfigurationTree().

◆ CmpWasSetupBoot

BOOLEAN CmpWasSetupBoot
extern

Definition at line 32 of file cmsysini.c.

Referenced by CmLoadKey(), and CmpCmdInit().

◆ CmSelfHeal

BOOLEAN CmSelfHeal
extern

Definition at line 63 of file cmdata.c.

Referenced by CmpInitializeSystemHive().

◆ CmSymbolicLinkValueName

UNICODE_STRING CmSymbolicLinkValueName
extern

Definition at line 52 of file cmdata.c.

Referenced by CmpCreateControlSet(), CmpGetSymbolicLink(), CmpLinkKeyToHive(), and CmSetValueKey().

◆ CmTypeName

UNICODE_STRING CmTypeName[]
extern

◆ ExpInTextModeSetup

BOOLEAN ExpInTextModeSetup
extern

Definition at line 69 of file init.c.

Referenced by CmpGetRegistryPath(), DisplayBootBitmap(), and ExpInitializeExecutive().

◆ HvShutdownComplete

BOOLEAN HvShutdownComplete
extern

Definition at line 36 of file cmsysini.c.

Referenced by CmpInitHiveFromFile(), and CmShutdownSystem().

◆ InitIsWinPEMode

BOOLEAN InitIsWinPEMode
extern

Definition at line 72 of file init.c.

Referenced by CmInitSystem1(), and Phase1InitializationDiscard().

◆ PsDefaultUILanguageId

LANGID PsDefaultUILanguageId
extern

Definition at line 25 of file locale.c.

Referenced by CmGetSystemControlValues().

◆ PsInstallUILanguageId

LANGID PsInstallUILanguageId
extern