Author: ion
Date: Wed May 9 22:30:21 2007
New Revision: 26666
URL:
http://svn.reactos.org/svn/reactos?rev=26666&view=rev
Log:
- Implement CmGetSystemControlValues and all related low-level Cm functionality required
to select the proper control set and read all the kernel variables during Phase 0
initialization. We can now read time-zone data, version, suite, language IDs and other
important kernel variables in the lowest-level boot phase.
- New code uses cmlib from Filip Navara without any modification, and is fully compatible
with reading Windows hives as well except XP's "Big value cells" (cells with
> 2GB data) which aren't supported.
- Create /config directory where the new Configuration Manager code lies.
Added:
trunk/reactos/ntoskrnl/config/
trunk/reactos/ntoskrnl/config/cm.h
trunk/reactos/ntoskrnl/config/cm_x.h
trunk/reactos/ntoskrnl/config/cmboot.c
trunk/reactos/ntoskrnl/config/cmcontrl.c
trunk/reactos/ntoskrnl/config/cmdata.c
trunk/reactos/ntoskrnl/config/cmindex.c
trunk/reactos/ntoskrnl/config/cmmapvw.c
trunk/reactos/ntoskrnl/config/cmname.c
trunk/reactos/ntoskrnl/config/cmparse.c
trunk/reactos/ntoskrnl/config/cmsecach.c
trunk/reactos/ntoskrnl/config/cmvalue.c
Removed:
trunk/reactos/ntoskrnl/cm/newcm.c
Modified:
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Removed: trunk/reactos/ntoskrnl/cm/newcm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/newcm.c?rev=26…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/newcm.c (original)
+++ trunk/reactos/ntoskrnl/cm/newcm.c (removed)
@@ -1,12 +1,0 @@
-#include "ntoskrnl.h"
-#include "cm.h"
-#include "debug.h"
-
-VOID
-NTAPI
-CmGetSystemControlValues(IN PVOID SystemHiveData,
- IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
-{
- return;
-}
-
Added: trunk/reactos/ntoskrnl/config/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (added)
+++ trunk/reactos/ntoskrnl/config/cm.h Wed May 9 22:30:21 2007
@@ -1,0 +1,968 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/cm/cm.h
+ * PURPOSE: Internal header for the Configuration Manager
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+#define _CM_
+#include "cmlib.h"
+
+//
+// Define this if you want debugging support
+//
+#define _CM_DEBUG_ 0x00
+
+//
+// These define the Debug Masks Supported
+//
+#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
+
+//
+// Debug/Tracing support
+//
+#if _CM_DEBUG_
+#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
+#define CMTRACE DbgPrintEx
+#else
+#define CMTRACE(x, ...) \
+ if (x & CmpTraceLevel) DbgPrint(__VA_ARGS__)
+#endif
+#else
+#define CMTRACE(x, ...) DPRINT(__VA_ARGS__)
+#endif
+
+//
+// Tag for all registry allocations
+//
+#define TAG_CM \
+ TAG('C', 'm', ' ', ' ')
+
+//
+// Hive operations
+//
+#define HINIT_CREATE 0
+#define HINIT_MEMORY 1
+#define HINIT_FILE 2
+#define HINIT_MEMORY_INPLACE 3
+#define HINIT_FLAT 4
+#define HINIT_MAPFILE 5
+
+//
+// Hive flags
+//
+#define HIVE_VOLATILE 1
+#define HIVE_NOLAZYFLUSH 2
+
+//
+// Hive types
+//
+#define HFILE_TYPE_PRIMARY 0
+#define HFILE_TYPE_ALTERNATE 1
+#define HFILE_TYPE_LOG 2
+#define HFILE_TYPE_EXTERNAL 3
+#define HFILE_TYPE_MAX 4
+
+//
+// Hive sizes
+//
+#define HBLOCK_SIZE 0x1000
+#define HSECTOR_SIZE 0x200
+#define HSECTOR_COUNT 8
+
+//
+// Hive versions
+//
+#define HSYS_MAJOR 1
+#define HSYS_MINOR 3
+#define HSYS_WHISTLER_BETA1 4
+
+//
+// Cell Masks
+//
+#define HCELL_NIL 0
+#define HCELL_CACHED 1
+
+//
+// Key Types
+//
+#define CM_KEY_INDEX_ROOT 0x6972
+#define CM_KEY_INDEX_LEAF 0x696c
+#define CM_KEY_FAST_LEAF 0x666c
+#define CM_KEY_HASH_LEAF 0x686c
+
+//
+// CM_KEY_CONTROL_BLOCK Flags
+//
+#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_KEY_READ_ONLY_KEY 0x80
+
+//
+// CM_KEY_NODE Signature and Flags
+//
+#define CM_KEY_NODE_SIGNATURE 0x6B6E
+#define CM_LINK_NODE_SIGNATURE 0x6B6C
+#define KEY_IS_VOLATILE 0x01
+#define KEY_HIVE_EXIT 0x02
+#define KEY_HIVE_ENTRY 0x04
+#define KEY_NO_DELETE 0x08
+#define KEY_SYM_LINK 0x10
+#define KEY_COMP_NAME 0x20
+#define KEY_PREFEF_HANDLE 0x40
+#define KEY_VIRT_MIRRORED 0x80
+#define KEY_VIRT_TARGET 0x100
+#define KEY_VIRTUAL_STORE 0x200
+
+//
+// CM_KEY_VALUE Signature and Flags
+//
+#define CM_KEY_VALUE_SIGNATURE 0x6b76
+#define CM_KEY_VALUE_SMALL 0x4
+#define CM_KEY_VALUE_BIG 0x3FD8
+#define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000
+#define VALUE_COMP_NAME 0x0001
+
+//
+// Number of various lists and hashes
+//
+#define CMP_SECURITY_HASH_LISTS 64
+#define CMP_MAX_CALLBACKS 100
+
+//
+// Hashing Constants
+//
+#define CMP_HASH_IRRATIONAL 314159269
+#define CMP_HASH_PRIME 1000000007
+
+//
+// CmpCreateKcb Flags
+//
+#define CMP_CREATE_FAKE_KCB 0x1
+#define CMP_LOCK_HASHES_FOR_KCB 0x2
+
+//
+// Number of items that can fit inside an Allocation Page
+//
+#define CM_KCBS_PER_PAGE \
+ PAGE_SIZE / sizeof(CM_KEY_CONTROL_BLOCK)
+#define CM_DELAYS_PER_PAGE \
+ PAGE_SIZE / sizeof(CM_DELAYED_CLOSE_ENTRY)
+
+//
+// Key Hash
+//
+typedef struct _CM_KEY_HASH
+{
+ ULONG ConvKey;
+ struct _CM_KEY_HASH *NextHash;
+ PHHIVE KeyHive;
+ HCELL_INDEX KeyCell;
+} CM_KEY_HASH, *PCM_KEY_HASH;
+
+//
+// Key Hash Table Entry
+//
+typedef struct _CM_KEY_HASH_TABLE_ENTRY
+{
+ EX_PUSH_LOCK Lock;
+ PKTHREAD Owner;
+ PCM_KEY_HASH Entry;
+} CM_KEY_HASH_TABLE_ENTRY, *PCM_KEY_HASH_TABLE_ENTRY;
+
+//
+// Name Hash
+//
+typedef struct _CM_NAME_HASH
+{
+ ULONG ConvKey;
+ struct _CM_NAME_HASH *NextHash;
+ USHORT NameLength;
+ WCHAR Name[ANYSIZE_ARRAY];
+} CM_NAME_HASH, *PCM_NAME_HASH;
+
+//
+// Name Hash Table Entry
+//
+typedef struct _CM_NAME_HASH_TABLE_ENTRY
+{
+ EX_PUSH_LOCK Lock;
+ PCM_NAME_HASH Entry;
+} CM_NAME_HASH_TABLE_ENTRY, *PCM_NAME_HASH_TABLE_ENTRY;
+
+//
+// Key Security Cache
+//
+typedef struct _CM_KEY_SECURITY_CACHE
+{
+ HCELL_INDEX Cell;
+ ULONG ConvKey;
+ LIST_ENTRY List;
+ ULONG DescriptorLength;
+ SECURITY_DESCRIPTOR_RELATIVE Descriptor;
+} CM_KEY_SECURITY_CACHE, *PCM_KEY_SECURITY_CACHE;
+
+//
+// Key Security Cache Entry
+//
+typedef struct _CM_KEY_SECURITY_CACHE_ENTRY
+{
+ HCELL_INDEX Cell;
+ PCM_KEY_SECURITY_CACHE CachedSecurity;
+} CM_KEY_SECURITY_CACHE_ENTRY, *PCM_KEY_SECURITY_CACHE_ENTRY;
+
+//
+// Cached Child List
+//
+typedef struct _CACHED_CHILD_LIST
+{
+ ULONG Count;
+ union
+ {
+ ULONG ValueList;
+ struct _CM_KEY_CONTROL_BLOCK *RealKcb;
+ };
+} CACHED_CHILD_LIST, *PCACHED_CHILD_LIST;
+
+//
+// Index Hint Block
+//
+typedef struct _CM_INDEX_HINT_BLOCK
+{
+ ULONG Count;
+ ULONG HashKey[ANYSIZE_ARRAY];
+} CM_INDEX_HINT_BLOCK, *PCM_INDEX_HINT_BLOCK;
+
+//
+// Key Reference
+//
+typedef struct _CM_KEY_REFERENCE
+{
+ HCELL_INDEX KeyCell;
+ PHHIVE KeyHive;
+} CM_KEY_REFERENCE, *PCM_KEY_REFERENCE;
+
+//
+// Key Body
+//
+typedef struct _CM_KEY_BODY
+{
+ ULONG Type;
+ struct _CM_KEY_CONTROL_BLOCK *KeyControlBlock;
+ struct _CM_NOTIFY_BLOCK *NotifyBlock;
+ HANDLE ProcessID;
+ ULONG Callers;
+ PVOID CallerAddress[10];
+ LIST_ENTRY KeyBodyList;
+} CM_KEY_BODY, *PCM_KEY_BODY;
+
+//
+// Name Control Block (NCB)
+//
+typedef struct _CM_NAME_CONTROL_BLOCK
+{
+ BOOLEAN Compressed;
+ USHORT RefCount;
+ union
+ {
+ CM_NAME_HASH NameHash;
+ struct
+ {
+ ULONG ConvKey;
+ PCM_KEY_HASH NextHash;
+ USHORT NameLength;
+ WCHAR Name[ANYSIZE_ARRAY];
+ };
+ };
+} CM_NAME_CONTROL_BLOCK, *PCM_NAME_CONTROL_BLOCK;
+
+//
+// Key Control Block (KCB)
+//
+typedef struct _CM_KEY_CONTROL_BLOCK
+{
+ USHORT RefCount;
+ USHORT Flags;
+ ULONG ExtFlags:8;
+ ULONG PrivateAlloc:1;
+ ULONG Delete:1;
+ ULONG DelayedCloseIndex:12;
+ ULONG TotalLevels:10;
+ union
+ {
+ CM_KEY_HASH KeyHash;
+ struct
+ {
+ ULONG ConvKey;
+ PCM_KEY_HASH NextHash;
+ PHHIVE KeyHive;
+ HCELL_INDEX KeyCell;
+ };
+ };
+ struct _CM_KEY_CONTROL_BLOCK *ParentKcb;
+ PCM_NAME_CONTROL_BLOCK NameBlock;
+ PCM_KEY_SECURITY_CACHE CachedSecurity;
+ CACHED_CHILD_LIST ValueCache;
+ PCM_INDEX_HINT_BLOCK IndexHint;
+ ULONG HashKey;
+ ULONG SubKeyCount;
+ union
+ {
+ LIST_ENTRY KeyBodyListHead;
+ LIST_ENTRY FreeListEntry;
+ };
+ PCM_KEY_BODY KeyBodyArray[4];
+ PVOID DelayCloseEntry;
+ LARGE_INTEGER KcbLastWriteTime;
+ USHORT KcbMaxNameLen;
+ USHORT KcbMaxValueNameLen;
+ ULONG KcbMaxValueDataLen;
+ ULONG InDelayClose;
+} CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;
+
+//
+// Notify Block
+//
+typedef struct _CM_NOTIFY_BLOCK
+{
+ LIST_ENTRY HiveList;
+ LIST_ENTRY PostList;
+ PCM_KEY_CONTROL_BLOCK KeyControlBlock;
+ PCM_KEY_BODY KeyBody;
+ ULONG Filter:29;
+ ULONG WatchTree:30;
+ ULONG NotifyPending:31;
+} CM_NOTIFY_BLOCK, *PCM_NOTIFY_BLOCK;
+
+//
+// Re-map Block
+//
+typedef struct _CM_CELL_REMAP_BLOCK
+{
+ HCELL_INDEX OldCell;
+ HCELL_INDEX NewCell;
+} CM_CELL_REMAP_BLOCK, *PCM_CELL_REMAP_BLOCK;
+
+//
+// Allocation Page
+//
+typedef struct _CM_ALLOC_PAGE
+{
+ ULONG FreeCount;
+ ULONG Reserved;
+ PVOID AllocPage;
+} CM_ALLOC_PAGE, *PCM_ALLOC_PAGE;
+
+//
+// Delayed Close Entry
+//
+typedef struct _CM_DELAYED_CLOSE_ENTRY
+{
+ LIST_ENTRY DelayedLRUList;
+ PCM_KEY_CONTROL_BLOCK KeyControlBlock;
+} CM_DELAYED_CLOSE_ENTRY, *PCM_DELAYED_CLOSE_ENTRY;
+
+//
+// Delayed KCB Dereference Entry
+//
+typedef struct _CM_DELAY_DEREF_KCB_ITEM
+{
+ LIST_ENTRY ListEntry;
+ PCM_KEY_CONTROL_BLOCK Kcb;
+} CM_DELAY_DEREF_KCB_ITEM, *PCM_DELAY_DEREF_KCB_ITEM;
+
+//
+// Use Count Log and Entry
+//
+typedef struct _CM_USE_COUNT_LOG_ENTRY
+{
+ HCELL_INDEX Cell;
+ PVOID Stack[7];
+} CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
+
+typedef struct _CM_USE_COUNT_LOG
+{
+ USHORT Next;
+ USHORT Size;
+ CM_USE_COUNT_LOG_ENTRY Log[32];
+} CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
+
+//
+// Configuration Manager Hive Structure
+//
+typedef struct _CMHIVE
+{
+ HHIVE Hive;
+ HANDLE FileHandles[3];
+ LIST_ENTRY NotifyList;
+ LIST_ENTRY HiveList;
+ EX_PUSH_LOCK HiveLock;
+ PKTHREAD HiveLockOwner;
+ PKGUARDED_MUTEX ViewLock;
+ PKTHREAD ViewLockOwner;
+ EX_PUSH_LOCK WriterLock;
+ PKTHREAD WriterLockOwner;
+ PERESOURCE FlusherLock;
+ EX_PUSH_LOCK SecurityLock;
+ PKTHREAD HiveSecurityLockOwner;
+ LIST_ENTRY LRUViewListHead;
+ LIST_ENTRY PinViewListHead;
+ PFILE_OBJECT FileObject;
+ UNICODE_STRING FileFullPath;
+ UNICODE_STRING FileUserName;
+ USHORT MappedViews;
+ USHORT PinnedViews;
+ ULONG UseCount;
+ ULONG SecurityCount;
+ ULONG SecurityCacheSize;
+ LONG SecurityHitHint;
+ PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
+ LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
+ PKEVENT UnloadEvent;
+ PCM_KEY_CONTROL_BLOCK RootKcb;
+ BOOLEAN Frozen;
+ PWORK_QUEUE_ITEM UnloadWorkItem;
+ BOOLEAN GrowOnlyMode;
+ ULONG GrowOffset;
+ LIST_ENTRY KcbConvertListHead;
+ LIST_ENTRY KnodeConvertListHead;
+ PCM_CELL_REMAP_BLOCK CellRemapArray;
+ CM_USE_COUNT_LOG UseCountLog;
+ CM_USE_COUNT_LOG LockHiveLog;
+ ULONG Flags;
+ LIST_ENTRY TrustClassEntry;
+ ULONG FlushCount;
+ BOOLEAN HiveIsLoading;
+ PKTHREAD CreatorOwner;
+} CMHIVE, *PCMHIVE;
+
+#include <pshpack1.h>
+
+typedef struct _CM_VIEW_OF_FILE
+{
+ LIST_ENTRY LRUViewList;
+ LIST_ENTRY PinViewList;
+ ULONG FileOffset;
+ ULONG Size;
+ PULONG ViewAddress;
+ PVOID Bcb;
+ ULONG UseCount;
+} CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
+
+typedef struct _CHILD_LIST
+{
+ ULONG Count;
+ HCELL_INDEX List;
+} CHILD_LIST, *PCHILD_LIST;
+
+typedef struct _CM_KEY_NODE
+{
+ USHORT Id;
+ USHORT Flags;
+ LARGE_INTEGER LastWriteTime;
+ ULONG Spare;
+ HCELL_INDEX Parent;
+ ULONG SubKeyCounts[HvMaxStorageType];
+ HCELL_INDEX SubKeyLists[HvMaxStorageType];
+ CHILD_LIST ValueList;
+ HCELL_INDEX SecurityKeyOffset;
+ HCELL_INDEX ClassNameOffset;
+ ULONG MaxNameLen;
+ ULONG MaxClassLen;
+ ULONG MaxValueNameLen;
+ ULONG MaxValueDataLen;
+ ULONG WorkVar;
+ USHORT NameLength;
+ USHORT ClassSize;
+ WCHAR Name[0];
+} CM_KEY_NODE, *PCM_KEY_NODE;
+
+typedef struct _VALUE_LIST_CELL
+{
+ HCELL_INDEX ValueOffset[0];
+} VALUE_LIST_CELL, *PVALUE_LIST_CELL;
+
+typedef struct _CM_KEY_VALUE
+{
+ USHORT Signature; // "kv"
+ USHORT NameLength; // length of Name
+ ULONG DataLength; // length of datas in the cell pointed by DataOffset
+ HCELL_INDEX Data;// datas are here if high bit of DataSize is set
+ ULONG Type;
+ USHORT Flags;
+ USHORT Unused1;
+ WCHAR Name[0]; /* warning : not zero terminated */
+} CM_KEY_VALUE, *PCM_KEY_VALUE;
+
+typedef struct _CM_KEY_SECURITY
+{
+ USHORT Signature; // "sk"
+ USHORT Reserved;
+ HCELL_INDEX Flink;
+ HCELL_INDEX Blink;
+ ULONG ReferenceCount;
+ ULONG DescriptorLength;
+ //SECURITY_DESCRIPTOR_RELATIVE Descriptor;
+ UCHAR Data[0];
+} CM_KEY_SECURITY, *PCM_KEY_SECURITY;
+
+#include <poppack.h>
+
+//
+// Generic Index Entry
+//
+typedef struct _CM_INDEX
+{
+ HCELL_INDEX Cell;
+ union
+ {
+ UCHAR NameHint[4];
+ ULONG HashKey;
+ };
+} CM_INDEX, *PCM_INDEX;
+
+//
+// Key Index
+//
+typedef struct _CM_KEY_INDEX
+{
+ USHORT Signature;
+ USHORT Count;
+ HCELL_INDEX List[ANYSIZE_ARRAY];
+} CM_KEY_INDEX, *PCM_KEY_INDEX;
+
+//
+// Fast/Hash Key Index
+//
+typedef struct _CM_KEY_FAST_INDEX
+{
+ USHORT Signature;
+ USHORT Count;
+ CM_INDEX List[ANYSIZE_ARRAY];
+} CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX;
+
+//
+// Cell Data
+//
+typedef struct _CELL_DATA
+{
+ union
+ {
+ CM_KEY_NODE KeyNode;
+ CM_KEY_VALUE KeyValue;
+ CM_KEY_SECURITY KeySecurity;
+ CM_KEY_INDEX KeyIndex;
+ HCELL_INDEX KeyList[ANYSIZE_ARRAY];
+ WCHAR KeyString[ANYSIZE_ARRAY];
+ } u;
+} CELL_DATA, *PCELL_DATA;
+
+//
+// Cached Value Index
+//
+typedef struct _CM_CACHED_VALUE_INDEX
+{
+ HCELL_INDEX CellIndex;
+ union
+ {
+ CELL_DATA CellData;
+ ULONG_PTR List[ANYSIZE_ARRAY];
+ } Data;
+} CM_CACHED_VALUE_INDEX, *PCM_CACHED_VALUE_INDEX;
+
+//
+// Cached Value
+//
+typedef struct _CM_CACHED_VALUE
+{
+ USHORT DataCacheType;
+ USHORT ValueKeySize;
+ CM_KEY_VALUE KeyValue;
+} CM_CACHED_VALUE, *PCM_CACHED_VALUE;
+
+//
+// Hive List Entry
+//
+typedef struct _HIVE_LIST_ENTRY
+{
+ PWCHAR FileName;
+ PWCHAR BaseName;
+ PWCHAR RegRootName;
+ PCMHIVE CmHive;
+ ULONG HHiveFlags;
+ ULONG CmHiveFlags;
+ PCMHIVE CmHive2;
+ BOOLEAN ThreadFinished;
+ BOOLEAN ThreadStarted;
+ BOOLEAN Allocate;
+ BOOLEAN WinPERequired;
+} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
+
+//
+// Parse context for Key Object
+//
+typedef struct _CM_PARSE_CONTEXT
+{
+ ULONG TitleIndex;
+ UNICODE_STRING Class;
+ ULONG CreateOptions;
+ ULONG Disposition;
+ CM_KEY_REFERENCE ChildHive;
+ BOOLEAN CreateLink;
+ BOOLEAN Flag2;
+ HANDLE PredefinedHandle;
+ ULONG PostActions;
+} CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT;
+
+//
+// System Control Vector
+//
+typedef struct _CM_SYSTEM_CONTROL_VECTOR
+{
+ PWCHAR KeyPath;
+ PWCHAR ValueName;
+ PVOID Buffer;
+ PULONG BufferLength;
+ PULONG Type;
+} CM_SYSTEM_CONTROL_VECTOR, *PCM_SYSTEM_CONTROL_VECTOR;
+
+//
+// Mapped View Hive Functions
+//
+VOID
+NTAPI
+CmpInitHiveViewList(
+ IN PCMHIVE Hive
+);
+
+//
+// Security Cache Functions
+//
+VOID
+NTAPI
+CmpInitSecurityCache(
+ IN PCMHIVE Hive
+);
+
+//
+// Registry Validation Functions
+//
+BOOLEAN
+NTAPI
+CmCheckRegistry(
+ IN PCMHIVE Hive,
+ IN BOOLEAN CleanFlag
+);
+
+//
+// Notification Routines
+//
+VOID
+CmpReportNotify(
+ IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN ULONG Filter
+);
+
+//
+// KCB Cache/Delay Routines
+//
+VOID
+NTAPI
+CmpInitializeCache(
+ VOID
+);
+
+VOID
+NTAPI
+CmpInitializeCmAllocations(
+ VOID
+);
+
+VOID
+NTAPI
+CmpInitializeKcbDelayedDeref(
+ VOID
+);
+
+//
+// Key Object Routines
+//
+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
+);
+
+//
+// Hive Routines
+//
+NTSTATUS
+NTAPI
+CmpInitializeHive(
+ OUT PCMHIVE *CmHive,
+ IN ULONG Operation,
+ IN ULONG Flags,
+ IN ULONG FileType,
+ IN PVOID HiveData,
+ IN HANDLE Primary,
+ IN HANDLE Alternate,
+ IN HANDLE Log,
+ IN HANDLE External,
+ IN PUNICODE_STRING FileName
+);
+
+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
+);
+
+//
+// Registry Utility Functions
+//
+BOOLEAN
+NTAPI
+CmpTestRegistryLockExclusive(
+ VOID
+);
+
+VOID
+NTAPI
+CmpLockRegistryExclusive(
+ VOID
+);
+
+VOID
+NTAPI
+CmpUnlockRegistry(
+ VOID
+);
+
+PVOID
+NTAPI
+CmpAllocateDelayItem(
+ VOID
+);
+
+VOID
+NTAPI
+CmpFreeDelayItem(
+ PVOID Entry
+);
+
+//
+// KCB Functions
+//
+PCM_KEY_CONTROL_BLOCK
+NTAPI
+CmpCreateKcb(
+ 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
+);
+
+VOID
+NTAPI
+CmpDereferenceKcbWithLock(
+ IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN BOOLEAN LockHeldExclusively
+);
+
+//
+// Name Functions
+//
+LONG
+NTAPI
+CmpCompareCompressedName(
+ IN PUNICODE_STRING SearchName,
+ IN PWCHAR CompressedName,
+ IN ULONG NameLength
+);
+
+USHORT
+NTAPI
+CmpNameSize(
+ IN PHHIVE Hive,
+ IN PUNICODE_STRING Name
+);
+
+USHORT
+NTAPI
+CmpCopyName(
+ IN PHHIVE Hive,
+ IN PWCHAR Destination,
+ IN PUNICODE_STRING Source
+);
+
+BOOLEAN
+NTAPI
+CmpFindNameInList(
+ IN PHHIVE Hive,
+ IN PCHILD_LIST ChildList,
+ IN PUNICODE_STRING Name,
+ IN PULONG ChildIndex,
+ IN PHCELL_INDEX CellIndex
+);
+
+//
+// Parse Routines
+//
+BOOLEAN
+NTAPI
+CmpGetNextName(
+ IN OUT PUNICODE_STRING RemainingName,
+ OUT PUNICODE_STRING NextName,
+ OUT PBOOLEAN LastName
+);
+
+//
+// Flush Routines
+//
+BOOLEAN
+NTAPI
+CmpFlushEntireRegistry(
+ IN BOOLEAN ForceFlush
+);
+
+//
+// Cell Index Routines
+//
+HCELL_INDEX
+NTAPI
+CmpFindSubKeyByName(
+ IN PHHIVE Hive,
+ IN PCM_KEY_NODE Parent,
+ IN PUNICODE_STRING SearchName
+);
+
+//
+// Cell Value Routines
+//
+HCELL_INDEX
+NTAPI
+CmpFindValueByName(
+ IN PHHIVE Hive,
+ IN PCM_KEY_NODE KeyNode,
+ IN PUNICODE_STRING Name
+);
+
+PCELL_DATA
+NTAPI
+CmpValueToData(
+ IN PHHIVE Hive,
+ IN PCM_KEY_VALUE Value,
+ OUT PULONG Length
+);
+
+//
+// Boot Routines
+//
+HCELL_INDEX
+NTAPI
+CmpFindControlSet(
+ IN PHHIVE SystemHive,
+ IN HCELL_INDEX RootCell,
+ IN PUNICODE_STRING SelectKeyName,
+ OUT PBOOLEAN AutoSelect
+);
+
+//
+// Global variables accessible from all of Cm
+//
+extern BOOLEAN CmpSpecialBootCondition;
+extern BOOLEAN CmpFlushOnLockRelease;
+extern EX_PUSH_LOCK CmpHiveListHeadLock;
+extern LIST_ENTRY CmpHiveListHead;
+extern POBJECT_TYPE CmpKeyObjectType;
+extern ERESOURCE CmpRegistryLock;
+extern PCM_KEY_HASH_TABLE_ENTRY *CmpCacheTable;
+extern PCM_NAME_HASH_TABLE_ENTRY *CmpNameCacheTable;
+extern KGUARDED_MUTEX CmpDelayedCloseTableLock;
+extern CMHIVE CmControlHive;
+extern WCHAR CmDefaultLanguageId[];
+extern ULONG CmDefaultLanguageIdLength;
+extern ULONG CmDefaultLanguageIdType;
+extern WCHAR CmInstallUILanguageId[];
+extern ULONG CmInstallUILanguageIdLength;
+extern ULONG CmInstallUILanguageIdType;
+extern LANGID PsInstallUILanguageId;
+extern LANGID PsDefaultUILanguageId;
+extern CM_SYSTEM_CONTROL_VECTOR CmControlVector[];
+
+//
+// Inlined functions
+//
+#include "cm_x.h"
Added: trunk/reactos/ntoskrnl/config/cm_x.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm_x.h?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm_x.h (added)
+++ trunk/reactos/ntoskrnl/config/cm_x.h Wed May 9 22:30:21 2007
@@ -1,0 +1,143 @@
+/*
+* PROJECT: ReactOS Kernel
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: ntoskrnl/cm/cm_x.h
+* PURPOSE: Inlined Functions for the Configuration Manager
+* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+*/
+
+//
+// Returns whether or not this is a small valued key
+//
+BOOLEAN
+FORCEINLINE
+CmpIsKeyValueSmall(OUT PULONG RealLength,
+ IN ULONG Length)
+{
+ /* Check if the length has the special size value */
+ if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
+ {
+ /* It does, so this is a small key: return the real length */
+ *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
+ return TRUE;
+ }
+
+ /* This is not a small key, return the length we read */
+ *RealLength = Length;
+ return FALSE;
+}
+
+//
+// Returns whether or not this is a big valued key
+//
+BOOLEAN
+FORCEINLINE
+CmpIsKeyValueBig(IN PHHIVE Hive,
+ IN ULONG Length)
+{
+ /* Check if the hive is XP Beta 1 or newer */
+ if (Hive->Version >= HSYS_WHISTLER_BETA1)
+ {
+ /* Check if the key length is valid for a big value key */
+ if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length >
CM_KEY_VALUE_BIG))
+ {
+ /* Yes, this value is big */
+ return TRUE;
+ }
+ }
+
+ /* Not a big value key */
+ return FALSE;
+}
+
+//
+// Returns the hashkey corresponding to a convkey
+//
+#define GET_HASH_KEY(ConvKey) \
+ ((CMP_HASH_IRRATIONAL * (ConvKey)) % CMP_HASH_PRIME)
+
+//
+// Returns the index into the hash table, or the entry itself
+//
+#define GET_HASH_INDEX(ConvKey) \
+ GET_HASH_KEY(ConvKey) % CmpHashTableSize
+#define GET_HASH_ENTRY(Table, ConvKey) \
+ (*Table[GET_HASH_INDEX(ConvKey)])
+
+//
+// Returns whether or not the cell is cached
+//
+#define CMP_IS_CELL_CACHED(c) \
+ (((c) & HCELL_CACHED) && ((c) != HCELL_NIL))
+
+//
+// Return data from a cached cell
+//
+#define CMP_GET_CACHED_CELL(c) \
+ (ULONG_PTR)((c) & ~HCELL_CACHED)
+#define CMP_GET_CACHED_DATA(c) \
+ (&(((PCM_CACHED_VALUE_INDEX)(CMP_GET_CACHED_CELL(c)))->Data.CellData))
+#define CMP_GET_CACHED_INDEX(c) \
+ (&(((PCM_CACHED_ENTRY)(CMP_GET_CACHED_CELL(c)))->CellIndex))
+#define CMP_GET_CACHED_VALUE(c) \
+ (&(((PCM_CACHED_VALUE)(CMP_GET_CACHED_CELL(c)))->KeyValue))
+
+//
+// Makes sure that the registry is locked
+//
+#define CMP_ASSERT_REGISTRY_LOCK() \
+ ASSERT((CmpSpecialBootCondition == TRUE) || \
+ (CmpTestRegistryLock() == TRUE))
+
+//
+// Makes sure that the registry is exclusively locked
+//
+#define CMP_ASSERT_EXCLUSIVE_REGISTRY_LOCK() \
+ ASSERT((CmpSpecialBootCondition == TRUE) || \
+ (CmpTestRegistryLockExclusive() == TRUE))
+
+//
+// Checks if a KCB is exclusively locked
+//
+#define CmpIsKcbLockedExclusive(k) \
+ (GET_HASH_ENTRY(CmpCacheTable, \
+ (k)->ConvKey).Owner == KeGetCurrentThread())
+
+//
+// Exclusively acquires a KCB
+//
+#define CmpAcquireKcbLockExclusive(k) \
+{ \
+ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpCacheTable, \
+ (k)->ConvKey).Lock); \
+ GET_HASH_ENTRY(CmpCacheTable, \
+ (k)->ConvKey).Owner = KeGetCurrentThread(); \
+}
+
+//
+// Releases an exlusively or shared acquired KCB
+//
+#define CmpReleaseKcbLock(k) \
+{ \
+ GET_HASH_ENTRY(CmpCacheTable, (k)->ConvKey).Owner = NULL; \
+ ExReleasePushLock(&GET_HASH_ENTRY(CmpCacheTable, \
+ (k)->ConvKey).Lock); \
+}
+
+//
+// Exclusively acquires an NCB
+//
+#define CmpAcquireNcbLockExclusive(n) \
+{ \
+ ExAcquirePushLockExclusive(&GET_HASH_ENTRY(CmpNameCacheTable, \
+ (n)->ConvKey).Lock); \
+}
+
+//
+// Releases an exlusively or shared acquired NCB
+//
+#define CmpReleaseNcbLock(k) \
+{ \
+ ExReleasePushLock(&GET_HASH_ENTRY(CmpNameCacheTable, \
+ (k)->ConvKey).Lock); \
+}
Added: trunk/reactos/ntoskrnl/config/cmboot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmboot.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmboot.c (added)
+++ trunk/reactos/ntoskrnl/config/cmboot.c Wed May 9 22:30:21 2007
@@ -1,0 +1,127 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmboot.c
+ * PURPOSE: Configuration Manager - Boot Initialization
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+HCELL_INDEX
+NTAPI
+CmpFindControlSet(IN PHHIVE SystemHive,
+ IN HCELL_INDEX RootCell,
+ IN PUNICODE_STRING SelectKeyName,
+ OUT PBOOLEAN AutoSelect)
+{
+ UNICODE_STRING KeyName;
+ PCM_KEY_NODE Node;
+ HCELL_INDEX SelectCell, AutoSelectCell, SelectValueCell, ControlSetCell;
+ HCELL_INDEX CurrentValueCell;
+ PCM_KEY_VALUE KeyValue;
+ ULONG Length;
+ PULONG ControlSetId;
+ ANSI_STRING ControlSetAnsiName;
+ CHAR Buffer[128];
+ WCHAR WideBuffer[128];
+ NTSTATUS Status;
+ PULONG CurrentData;
+
+ /* Sanity check */
+ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
+
+ /* Get the Select subkey */
+ RtlInitUnicodeString(&KeyName, L"select");
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
+ if (!Node) return HCELL_NIL;
+ SelectCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
+ if (SelectCell == HCELL_NIL) return SelectCell;
+
+ /* Get AutoSelect value */
+ RtlInitUnicodeString(&KeyName, L"AutoSelect");
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
+ if (!Node) return HCELL_NIL;
+ AutoSelectCell = CmpFindValueByName(SystemHive, Node, &KeyName);
+ if (AutoSelectCell == HCELL_NIL)
+ {
+ /* Assume TRUE if the value is missing. */
+ *AutoSelect = TRUE;
+ }
+ else
+ {
+ /* Read the value */
+ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, AutoSelectCell);
+ if (KeyValue == NULL) return HCELL_NIL;
+
+ /* Convert it to a boolean */
+ *AutoSelect = *(PBOOLEAN)CmpValueToData(SystemHive, KeyValue, &Length);
+ }
+
+ /* Now find the control set being looked up */
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
+ if (!Node) return HCELL_NIL;
+ SelectValueCell = CmpFindValueByName(SystemHive, Node, SelectKeyName);
+ if (SelectValueCell == HCELL_NIL) return SelectValueCell;
+
+ /* Read the value (corresponding to the CCS ID) */
+ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, SelectValueCell);
+ if (!KeyValue) return HCELL_NIL;
+ if (KeyValue->Type != REG_DWORD) return HCELL_NIL;
+ ControlSetId = (PULONG)CmpValueToData(SystemHive, KeyValue, &Length);
+
+ /* Now build an Ansi String for the CCS's Name */
+ sprintf(Buffer, "ControlSet%03lu", *ControlSetId);
+ ControlSetAnsiName.Length = (USHORT)strlen(Buffer);
+ ControlSetAnsiName.MaximumLength = (USHORT)strlen(Buffer);
+ ControlSetAnsiName.Buffer = Buffer;
+
+ /* And convert it to Unicode... */
+ KeyName.MaximumLength = 256;
+ KeyName.Buffer = WideBuffer;
+ Status = RtlAnsiStringToUnicodeString(&KeyName,
+ &ControlSetAnsiName,
+ FALSE);
+ if (!NT_SUCCESS(Status)) return HCELL_NIL;
+
+ /* Now open it */
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, RootCell);
+ if (!Node) return HCELL_NIL;
+ ControlSetCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
+ if (ControlSetCell == HCELL_NIL) return ControlSetCell;
+
+ /* Get the value of the "Current" CCS */
+ RtlInitUnicodeString(&KeyName, L"Current");
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, SelectCell);
+ if (!Node) return HCELL_NIL;
+ CurrentValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
+
+ /* Make sure it exists */
+ if (CurrentValueCell != HCELL_NIL)
+ {
+ /* Get the current value and make sure its a ULONG */
+ KeyValue = (PCM_KEY_VALUE)HvGetCell(SystemHive, CurrentValueCell);
+ if (!KeyValue) return HCELL_NIL;
+ if (KeyValue->Type == REG_DWORD)
+ {
+ /* Get the data and update it */
+ CurrentData = (PULONG)CmpValueToData(SystemHive,
+ KeyValue,
+ &Length);
+ if (!CurrentData) return HCELL_NIL;
+ *CurrentData = *ControlSetId;
+ }
+ }
+
+ /* Return the CCS Cell */
+ return ControlSetCell;
+}
Added: trunk/reactos/ntoskrnl/config/cmcontrl.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmcontrl.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmcontrl.c (added)
+++ trunk/reactos/ntoskrnl/config/cmcontrl.c Wed May 9 22:30:21 2007
@@ -1,0 +1,262 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmcontrl.c
+ * PURPOSE: Configuration Manager - Control Set Management
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+LANGID
+NTAPI
+CmpConvertLangId(IN LPWSTR Name,
+ IN ULONG NameLength)
+{
+ ULONG i;
+ WCHAR p;
+ LANGID LangId = 0;
+ ULONG IdCode;
+
+ /* Convert the length in chars and loop */
+ NameLength = NameLength / sizeof(WCHAR);
+ for (i = 0; i < NameLength; i++)
+ {
+ /* Get the character */
+ p = Name[i];
+
+ /* Handle each case */
+ if ((p >= L'0') && (p <= L'9'))
+ {
+ /* Handle digits*/
+ IdCode = p - L'0';
+ }
+ else if ((p >= L'A') && (p <= L'F'))
+ {
+ /* Handle upper-case letters */
+ IdCode = p - L'A' + 10;
+ }
+ else if ((p >= L'a') && (p <= L'f'))
+ {
+ /* Handle lower-case letters */
+ IdCode = p - L'a' + 10;
+ }
+ else
+ {
+ /* Unhandled case, return what we have till now */
+ break;
+ }
+
+ /* If the ID Code is >= 16, then we're done */
+ if (IdCode >= 16) break;
+
+ /* Build the Language ID */
+ LangId = (LangId << 4) | (LANGID)IdCode;
+ }
+
+ /* Return the Language ID */
+ return LangId;
+}
+
+HCELL_INDEX
+NTAPI
+CmpWalkPath(IN PHHIVE SystemHive,
+ IN HCELL_INDEX ParentCell,
+ IN LPWSTR Path)
+{
+ UNICODE_STRING UnicodePath, NextName;
+ BOOLEAN LastName;
+ HCELL_INDEX CurrentCell = ParentCell;
+ PCM_KEY_NODE Node;
+
+ /* We shouldn't have a release routine at this point */
+ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
+
+ /* Initialize the Unicode path and start looping */
+ RtlInitUnicodeString(&UnicodePath, Path);
+ while (TRUE)
+ {
+ /* Get the next name */
+ CmpGetNextName(&UnicodePath, &NextName, &LastName);
+ if (!NextName.Length) return CurrentCell;
+
+ /* Get the subkey */
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, CurrentCell);
+ if (!Node) return HCELL_NIL;
+ CurrentCell = CmpFindSubKeyByName(SystemHive, Node, &NextName);
+ if (CurrentCell == HCELL_NIL) return CurrentCell;
+ }
+}
+
+VOID
+NTAPI
+CmGetSystemControlValues(IN PVOID SystemHiveData,
+ IN PCM_SYSTEM_CONTROL_VECTOR ControlVector)
+{
+ PHHIVE SystemHive = (PHHIVE)&CmControlHive;
+ NTSTATUS Status;
+ HCELL_INDEX RootCell, BaseCell, KeyCell, ValueCell;
+ ULONG Length, DataSize;
+ PCM_KEY_NODE Node;
+ PCM_KEY_VALUE ValueData;
+ UNICODE_STRING KeyName;
+ BOOLEAN Auto, IsSmallKey;
+ PVOID Buffer;
+
+ /* Initialize the Hive View List and the security cache */
+ RtlZeroMemory(SystemHive, sizeof(SystemHive));
+ CmpInitHiveViewList((PCMHIVE)SystemHive);
+ CmpInitSecurityCache((PCMHIVE)SystemHive);
+
+ /* Initialize the Hive */
+ Status = HvInitialize(SystemHive,
+ HINIT_MEMORY_INPLACE, /* FIXME: Should be flat */
+ HIVE_VOLATILE,
+ HFILE_TYPE_PRIMARY,
+ (ULONG_PTR)SystemHiveData,
+ 1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status)) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 1, 0, 0);
+
+ /* Sanity check, flat hives don't have release routines */
+ ASSERT(SystemHive->ReleaseCellRoutine == NULL);
+
+ /* FIXME: Prepare it */
+ CmPrepareHive(SystemHive);
+
+ /* Set the Root Cell */
+ RootCell = ((PHBASE_BLOCK)SystemHiveData)->RootCell;
+
+ /* Find the current control set */
+ RtlInitUnicodeString(&KeyName, L"current");
+ BaseCell = CmpFindControlSet(SystemHive, RootCell, &KeyName, &Auto);
+ if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 1, 2, 0, 0);
+
+ /* Find the control subkey */
+ RtlInitUnicodeString(&KeyName, L"control");
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, BaseCell);
+ BaseCell = CmpFindSubKeyByName(SystemHive, Node, &KeyName);
+ if (BaseCell == HCELL_NIL) KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO,1 , 3, 0, 0);
+
+ /* Loop each key */
+ while (ControlVector->KeyPath)
+ {
+ /* Assume failure */
+ Length = -1;
+
+ /* Get the cell for this key */
+ KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
+ if (KeyCell != HCELL_NIL)
+ {
+ /* Now get the cell for the value */
+ RtlInitUnicodeString(&KeyName, ControlVector->ValueName);
+ Node = (PCM_KEY_NODE)HvGetCell(SystemHive, KeyCell);
+ ValueCell = CmpFindValueByName(SystemHive, Node, &KeyName);
+ if (ValueCell != HCELL_NIL)
+ {
+ /* Check if there's any data */
+ if (!ControlVector->BufferLength)
+ {
+ /* No, the buffer will only be large enough for a ULONG */
+ DataSize = sizeof(ULONG);
+ }
+ else
+ {
+ /* Yes, save the data size */
+ DataSize = *ControlVector->BufferLength;
+ }
+
+ /* Get the actual data */
+ ValueData = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
+
+ /* Check if this is a small key */
+ IsSmallKey = CmpIsKeyValueSmall(&Length, ValueData->DataLength);
+
+ /* If the length is bigger then our buffer, normalize it */
+ if (DataSize < Length) Length = DataSize;
+
+ /* Make sure we have some data */
+ if (Length > 0)
+ {
+ /* Check if this was a small key */
+ if (IsSmallKey)
+ {
+ /* The buffer is directly safe to read */
+ Buffer = (PVOID)(&(ValueData->Data));
+ }
+ else
+ {
+ /* Use the longer path */
+ Buffer = (PVOID)HvGetCell(SystemHive, ValueData->Data);
+ }
+
+ /* Sanity check if this is a small key */
+ ASSERT((IsSmallKey ?
+ (Length <= CM_KEY_VALUE_SMALL) : TRUE));
+
+ /* Copy the data in the buffer */
+ RtlCopyMemory(ControlVector->Buffer, Buffer, Length);
+ }
+
+ /* Check if we should return the data type */
+ if (ControlVector->Type)
+ {
+ /* Return the type that we read */
+ *ControlVector->Type = ValueData->Type;
+ }
+ }
+ }
+
+ /* Return the size that we read */
+ if (ControlVector->BufferLength) *ControlVector->BufferLength = Length;
+
+ /* Go to the next entry */
+ ControlVector++;
+ }
+
+ /* Check if the ID is in the registry */
+ if (CmDefaultLanguageIdType == REG_SZ)
+ {
+ /* Read it */
+ PsDefaultSystemLocaleId =
+ (LCID)CmpConvertLangId(CmDefaultLanguageId,
+ CmDefaultLanguageIdLength);
+ }
+ else
+ {
+ /* Use EN_US by default */
+ PsDefaultSystemLocaleId = 0x409;
+ }
+
+ /* Check if the ID Is in the registry */
+ if (CmInstallUILanguageIdType == REG_SZ)
+ {
+ /* Read it */
+ PsInstallUILanguageId = CmpConvertLangId(CmInstallUILanguageId,
+ CmInstallUILanguageIdLength);
+ }
+ else
+ {
+ /* Otherwise, use the default */
+ PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId);
+ }
+
+ /* Set the defaults for the Thread UI */
+ PsDefaultThreadLocaleId = PsDefaultSystemLocaleId;
+ PsDefaultUILanguageId = PsInstallUILanguageId;
+}
Added: trunk/reactos/ntoskrnl/config/cmdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdata.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmdata.c (added)
+++ trunk/reactos/ntoskrnl/config/cmdata.c Wed May 9 22:30:21 2007
@@ -1,0 +1,718 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmdata.c
+ * PURPOSE: Configuration Manager - Global Configuration Data
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+ULONG DummyData;
+ULONG CmNtGlobalFlag;
+ULONG CmNtCSDVersion;
+
+WCHAR CmDefaultLanguageId[12];
+ULONG CmDefaultLanguageIdLength = sizeof(CmDefaultLanguageId);
+ULONG CmDefaultLanguageIdType;
+
+WCHAR CmInstallUILanguageId[12];
+ULONG CmInstallUILanguageIdLength = sizeof(CmInstallUILanguageId);
+ULONG CmInstallUILanguageIdType;
+
+WCHAR CmSuiteBuffer[128];
+ULONG CmSuiteBufferLength = sizeof(CmSuiteBuffer);
+ULONG CmSuiteBufferType;
+
+CMHIVE CmControlHive;
+
+CM_SYSTEM_CONTROL_VECTOR CmControlVector[] =
+{
+ {
+ L"Session Manager",
+ L"ProtectionMode",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"ObjectSecurityMode",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"LUIDDeviceMapsDisabled",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"LSA",
+ L"AuditBaseDirectories",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"LSA",
+ L"AuditBaseObjects",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"LSA\\audit",
+ L"ProcessAccessesToAudit",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"TimeZoneInformation",
+ L"ActiveTimeBias",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"TimeZoneInformation",
+ L"Bias",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"TimeZoneInformation",
+ L"RealTimeIsUniversal",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"GlobalFlag",
+ &CmNtGlobalFlag,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PagedPoolQuota",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"NonPagedPoolQuota",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PagingFileQuota",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"AllocationPreference",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"DynamicMemory",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"Mirroring",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"Mirroring",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SystemViewSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SessionViewSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SessionImageSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SessionPoolSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PoolUsageMaximum",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"MapAllocationFragment",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PagedPoolSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"NonPagedPoolSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"NonPagedPoolMaximumPercent",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"LargeSystemCache",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"LargeStackSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SystemPages",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"LowMemoryThreshold",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"HighMemoryThreshold",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"DisablePagingExecutive",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"ModifiedPageLife",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SecondLevelDataCache",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"ClearPageFileAtShutdown",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PoolTagSmallTableSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PoolTagBigTableSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PoolTag",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"PoolTagOverruns",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"SnapUnloads",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"ProtectNonPagedPool",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"TrackLockedPages",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"TrackPtes",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"VerifyDrivers",
+ &DummyData,
+ &DummyData,
+ &DummyData
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"VerifyDriverLevel",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"VerifyMode",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"LargePageMinimum",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"EnforceWriteProtection",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"MakeLowMemory",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Memory Management",
+ L"WriteWatch",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Executive",
+ L"AdditionalCriticalWorkerThreads",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Executive",
+ L"AdditionalDelayedWorkerThreads",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Executive",
+ L"PriorityQuantumMatrix",
+ &DummyData,
+ &DummyData,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Kernel",
+ L"DpcQueueDepth",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Kernel",
+ L"MinimumDpcRate",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Kernel",
+ L"AdjustDpcThreshold",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Kernel",
+ L"IdealDpcRate",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\I/O System",
+ L"CountOperations",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\I/O System",
+ L"LargeIrpStackLocations",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\I/O System",
+ L"IoVerifierLevel",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"ResourceTimeoutCount",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"CriticalSectionTimeout",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"HeapSegmentReserve",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"HeapSegmentCommit",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"HeapDeCommitTotalFreeThreshold",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"HeapDeCommitFreeBlockThreshold",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"ProductOptions",
+ L"ProductType",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Terminal Server",
+ L"TSEnabled",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Terminal Server",
+ L"TSAppCompat",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+
+ {
+ L"ProductOptions",
+ L"ProductSuite",
+ CmSuiteBuffer,
+ &CmSuiteBufferLength,
+ &CmSuiteBufferType
+ },
+
+ {
+ L"Windows",
+ L"CSDVersion",
+ &CmNtCSDVersion,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Nls\\Language",
+ L"Default",
+ CmDefaultLanguageId,
+ &CmDefaultLanguageIdLength,
+ &CmDefaultLanguageIdType
+ },
+
+ {
+ L"Nls\\Language",
+ L"InstallLanguage",
+ CmInstallUILanguageId,
+ &CmInstallUILanguageIdLength,
+ &CmInstallUILanguageIdType
+ },
+
+ {
+ L"\0\0",
+ L"RegistrySizeLimit",
+ &DummyData,
+ &DummyData,
+ &DummyData
+ },
+
+ {
+ L"Session Manager",
+ L"ForceNpxEmulation",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"PowerPolicySimulate",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager\\Executive",
+ L"MaxTimeSeparationBeforeCorrect",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Windows",
+ L"ShutdownTime",
+ &DummyData,
+ &DummyData,
+ NULL
+ },
+
+ {
+ L"PriorityControl",
+ L"Win32PrioritySeparation",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"EnableTimerWatchdog",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"Session Manager",
+ L"Debugger Retries",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"WMI",
+ L"MaxEventSize",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"WMI\\Trace",
+ L"UsePerformanceClock",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ L"WMI\\Trace",
+ L"TraceAlignment",
+ &DummyData,
+ NULL,
+ NULL
+ },
+
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+};
Added: trunk/reactos/ntoskrnl/config/cmindex.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmindex.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmindex.c (added)
+++ trunk/reactos/ntoskrnl/config/cmindex.c Wed May 9 22:30:21 2007
@@ -1,0 +1,646 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmindex.c
+ * PURPOSE: Configuration Manager - Cell Indexes
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+LONG
+NTAPI
+CmpDoCompareKeyName(IN PHHIVE Hive,
+ IN PUNICODE_STRING SearchName,
+ IN HCELL_INDEX Cell)
+{
+ PCM_KEY_NODE Node;
+ UNICODE_STRING KeyName;
+ LONG Result;
+
+ /* Get the node */
+ Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
+ if (!Node) return 2;
+
+ /* Check if it's compressed */
+ if (Node->Flags & KEY_COMP_NAME)
+ {
+ /* Compare compressed names */
+ Result = CmpCompareCompressedName(SearchName,
+ Node->Name,
+ Node->NameLength);
+ }
+ else
+ {
+ /* Compare the Unicode name directly */
+ KeyName.Buffer = Node->Name;
+ KeyName.Length = Node->NameLength;
+ KeyName.MaximumLength = KeyName.Length;
+ Result = RtlCompareUnicodeString(SearchName, &KeyName, TRUE);
+ }
+
+ /* Release the cell and return the normalized result */
+ HvReleaseCell(Hive, Cell);
+ return (Result == 0) ? Result : ((Result > 0) ? 1 : -1);
+}
+
+LONG
+NTAPI
+CmpCompareInIndex(IN PHHIVE Hive,
+ IN PUNICODE_STRING SearchName,
+ IN ULONG Count,
+ IN PCM_KEY_INDEX Index,
+ IN PHCELL_INDEX SubKey)
+{
+ PCM_KEY_FAST_INDEX FastIndex;
+ PCM_INDEX FastEntry;
+ LONG Result;
+ ULONG i;
+ ULONG ActualNameLength = 4, CompareLength, NameLength;
+ WCHAR p, pp;
+
+ /* Assume failure */
+ *SubKey = HCELL_NIL;
+
+ /* Check if we are a fast or hashed leaf */
+ if ((Index->Signature == CM_KEY_FAST_LEAF) ||
+ (Index->Signature == CM_KEY_HASH_LEAF))
+ {
+ /* Get the Fast/Hash Index */
+ FastIndex = (PCM_KEY_FAST_INDEX)Index;
+ FastEntry = &FastIndex->List[Count];
+
+ /* Check if we are a hash leaf, in which case we skip all this */
+ if (Index->Signature == CM_KEY_FAST_LEAF)
+ {
+ /* Find out just how much of the name is there */
+ for (i = 0; i < 4; i++)
+ {
+ /* Check if this entry is empty */
+ if (!FastEntry->NameHint[i])
+ {
+ /* Only this much! */
+ ActualNameLength = i;
+ break;
+ }
+ }
+
+ /* How large is the name and how many characters to compare */
+ NameLength = SearchName->Length / sizeof(WCHAR);
+ CompareLength = min(NameLength, ActualNameLength);
+
+ /* Loop all the chars we'll test */
+ for (i = 0; i < CompareLength; i++)
+ {
+ /* Get one char from each buffer */
+ p = SearchName->Buffer[i];
+ pp = FastEntry->NameHint[i];
+
+ /* See if they match and return result if they don't */
+ Result = (LONG)RtlUpcaseUnicodeChar(p) -
+ (LONG)RtlUpcaseUnicodeChar(pp);
+ if (Result) return (Result > 0) ? 1 : -1;
+ }
+ }
+
+ /* If we got here then we have to do a full compare */
+ Result = CmpDoCompareKeyName(Hive, SearchName, FastEntry->Cell);
+ if (Result == 2) return Result;
+ if (!Result) *SubKey = FastEntry->Cell;
+ }
+ else
+ {
+ /* We aren't, so do a name compare and return the subkey found */
+ Result = CmpDoCompareKeyName(Hive, SearchName, Index->List[Count]);
+ if (Result == 2) return Result;
+ if (!Result) *SubKey = Index->List[Count];
+ }
+
+ /* Return the comparison result */
+ return Result;
+}
+
+ULONG
+NTAPI
+CmpFindSubKeyInRoot(IN PHHIVE Hive,
+ IN PCM_KEY_INDEX Index,
+ IN PUNICODE_STRING SearchName,
+ IN PHCELL_INDEX SubKey)
+{
+ ULONG High, Low = 0, i, ReturnIndex;
+ HCELL_INDEX LeafCell;
+ PCM_KEY_INDEX Leaf;
+ LONG Result;
+
+ /* Verify Index for validity */
+ ASSERTMSG("We don't do a linear search yet!\n", FALSE);
+ ASSERT(Index->Count != 0);
+ ASSERT(Index->Signature == CM_KEY_INDEX_ROOT);
+
+ /* Set high limit and loop */
+ High = Index->Count - 1;
+ while (TRUE)
+ {
+ /* Choose next entry */
+ i = ((High - Low) / 2) + Low;
+
+ /* Get the leaf cell and then the leaf itself */
+ LeafCell = Index->List[i];
+ Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
+ if (Leaf)
+ {
+ /* Make sure the leaf is valid */
+ ASSERT((Leaf->Signature == CM_KEY_INDEX_LEAF) ||
+ (Leaf->Signature == CM_KEY_FAST_LEAF) ||
+ (Leaf->Signature == CM_KEY_HASH_LEAF));
+ ASSERT(Leaf->Count != 0);
+
+ /* Do the compare */
+ Result = CmpCompareInIndex(Hive,
+ SearchName,
+ Leaf->Count - 1,
+ Leaf,
+ SubKey);
+ if (Result == 2) goto Big;
+
+ /* Check if we found the leaf */
+ if (!Result)
+ {
+ /* We found the leaf */
+ *SubKey = LeafCell;
+ ReturnIndex = i;
+ goto Return;
+ }
+
+ /* Check for negative result */
+ if (Result < 0)
+ {
+ /* If we got here, we should be at -1 */
+ ASSERT(Result == -1);
+
+ /* Do another lookup, since we might still be in the right leaf */
+ Result = CmpCompareInIndex(Hive,
+ SearchName,
+ 0,
+ Leaf,
+ SubKey);
+ if (Result == 2) goto Big;
+
+ /* Check if it's not below */
+ if (Result >= 0)
+ {
+ /*
+ * If the name was first below, and now it is above,
+ * then this means that it is somewhere in this leaf.
+ * Make sure we didn't get some weird result
+ */
+ ASSERT((Result == 1) || (Result == 0));
+
+ /* Return it */
+ *SubKey = LeafCell;
+ ReturnIndex = Low;
+ goto Return;
+ }
+
+ /* Update the limit to this index, since we know it's not higher. */
+ High = i;
+ }
+ else
+ {
+ /* Update the base to this index, since we know it's not lower. */
+ Low = i;
+ }
+ }
+ else
+ {
+Big:
+ /* This was some sort of special key */
+ ReturnIndex = 0x80000000;
+ goto ReturnFailure;
+ }
+
+ /* Check if there is only one entry left */
+ if ((High - Low) <= 1) break;
+
+ /* Release the leaf cell */
+ HvReleaseCell(Hive, LeafCell);
+ }
+
+ /* Make sure we got here for the right reasons */
+ ASSERT((High - Low == 1) || (High == Low));
+
+ /* Get the leaf cell and the leaf */
+ LeafCell = Index->List[Low];
+ Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
+ if (!Leaf) goto Big;
+
+ /* Do the compare */
+ Result = CmpCompareInIndex(Hive,
+ SearchName,
+ Leaf->Count-1,
+ Leaf,
+ SubKey);
+ if (Result == 2) goto Big;
+
+ /* Check if we found it */
+ if (!Result)
+ {
+ /* We got lucky...return it */
+ *SubKey = LeafCell;
+ ReturnIndex = Low;
+ goto Return;
+ }
+
+ /* It's below, so could still be in this leaf */
+ if (Result < 0)
+ {
+ /* Make sure we're -1 */
+ ASSERT(Result == -1);
+
+ /* Do a search from the bottom */
+ Result = CmpCompareInIndex(Hive, SearchName, 0, Leaf, SubKey);
+ if (Result == 2) goto Big;
+
+ /*
+ * Check if it's above, which means that it's within the ranges of our
+ * leaf (since we were below before).
+ */
+ if (Result >= 0)
+ {
+ /* Sanity check */
+ ASSERT((Result == 1) || (Result == 0));
+
+ /* Yep, so we're in the right leaf; return it. */
+ *SubKey = LeafCell;
+ ReturnIndex = Low;
+ goto Return;
+ }
+
+ /* It's still below us, so fail */
+ ReturnIndex = Low;
+ goto ReturnFailure;
+ }
+
+ /* Release the leaf cell */
+ HvReleaseCell(Hive, LeafCell);
+
+ /* Well the low didn't work too well, so try the high. */
+ LeafCell = Index->List[High];
+ Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
+ if (!Leaf) goto Big;
+
+ /* Do the compare */
+ Result = CmpCompareInIndex(Hive,
+ SearchName,
+ Leaf->Count - 1,
+ Leaf,
+ SubKey);
+ if (Result == 2) goto Big;
+
+ /* Check if we found it */
+ if (Result == 0)
+ {
+ /* We got lucky... return it */
+ *SubKey = LeafCell;
+ ReturnIndex = High;
+ goto Return;
+ }
+
+ /* Check if we are too high */
+ if (Result < 0)
+ {
+ /* Make sure we're -1 */
+ ASSERT(Result == -1);
+
+ /*
+ * Once again... since we were first too low and now too high, then
+ * this means we are within the range of this leaf... return it.
+ */
+ *SubKey = LeafCell;
+ ReturnIndex = High;
+ goto Return;
+ }
+
+ /* If we got here, then we are too low, again. */
+ ReturnIndex = High;
+
+ /* Failure path */
+ReturnFailure:
+ *SubKey = HCELL_NIL;
+
+ /* Return path...check if we have a leaf to free */
+Return:
+ if (Leaf) HvReleaseCell(Hive, LeafCell);
+
+ /* Return the index */
+ return ReturnIndex;
+}
+
+ULONG
+NTAPI
+CmpFindSubKeyInLeaf(IN PHHIVE Hive,
+ IN PCM_KEY_INDEX Index,
+ IN PUNICODE_STRING SearchName,
+ IN PHCELL_INDEX SubKey)
+{
+ ULONG High, Low = 0, i;
+ LONG Result;
+
+ /* Verify Index for validity */
+ ASSERT((Index->Signature == CM_KEY_INDEX_LEAF) ||
+ (Index->Signature == CM_KEY_FAST_LEAF) ||
+ (Index->Signature == CM_KEY_HASH_LEAF));
+
+ /* Get the upper bound and middle entry */
+ High = Index->Count - 1;
+#ifdef SOMEONE_WAS_NICE_ENOUGH_TO_MAKE_OUR_CELLS_LEXICALLY_SORTED
+ i = High / 2;
+#else
+ i = 0;
+#endif
+
+ /* Check if we don't actually have any entries */
+ if (!Index->Count)
+ {
+ /* Return failure */
+ *SubKey = HCELL_NIL;
+ return 0;
+ }
+
+ /* Start compare loop */
+ while (TRUE)
+ {
+ /* Do the actual comparison and check the result */
+ Result = CmpCompareInIndex(Hive, SearchName, i, Index, SubKey);
+ if (Result == 2)
+ {
+ /* Fail with special value */
+ *SubKey = HCELL_NIL;
+ return 0x80000000;
+ }
+
+ /* Check if we got lucky and found it */
+ if (!Result) return i;
+
+ /* Check if the result is below us */
+ if (Result < 0)
+ {
+ /* Set the new bound; it can't be higher then where we are now. */
+ ASSERT(Result == -1);
+ High = i;
+ }
+ else
+ {
+ /* Set the new bound... it can't be lower then where we are now. */
+ ASSERT(Result == 1);
+ Low = i;
+ }
+
+#ifdef SOMEONE_WAS_NICE_ENOUGH_TO_MAKE_OUR_CELLS_LEXICALLY_SORTED
+ /* Check if this is the last entry, if so, break out and handle it */
+ if ((High - Low) <= 1) break;
+
+ /* Set the new index */
+ i = ((High - Low) / 2) + Low;
+#else
+ if (++i > High)
+ {
+ /* Return failure */
+ *SubKey = HCELL_NIL;
+ return 0;
+ }
+#endif
+ }
+
+ /*
+ * If we get here, High - Low = 1 or High == Low
+ * Simply look first at Low, then at High
+ */
+ Result = CmpCompareInIndex(Hive, SearchName, Low, Index, SubKey);
+ if (Result == 2)
+ {
+ /* Fail with special value */
+ *SubKey = HCELL_NIL;
+ return 0x80000000;
+ }
+
+ /* Check if we got lucky and found it */
+ if (!Result) return Low;
+
+ /* Check if the result is below us */
+ if (Result < 0)
+ {
+ /* Return the low entry */
+ ASSERT(Result == -1);
+ return Low;
+ }
+
+ /*
+ * If we got here, then just check the high and return it no matter what
+ * the result is (since we're a leaf, it has to be near there anyway).
+ */
+ Result = CmpCompareInIndex(Hive, SearchName, High, Index, SubKey);
+ if (Result == 2)
+ {
+ /* Fail with special value */
+ *SubKey = HCELL_NIL;
+ return 0x80000000;
+ }
+
+ /* Return the high */
+ return High;
+}
+
+ULONG
+NTAPI
+CmpComputeHashKey(IN ULONG Hash,
+ IN PUNICODE_STRING Name,
+ IN BOOLEAN AllowSeparators)
+{
+ LPWSTR Cp;
+ ULONG Value, i;
+
+ /* Make some sanity checks on our parameters */
+ ASSERT((Name->Length == 0) ||
+ (AllowSeparators) ||
+ (Name->Buffer[0] != OBJ_NAME_PATH_SEPARATOR));
+
+ /* If the name is empty, there is nothing to hash! */
+ if (!Name->Length) return Hash;
+
+ /* Set the buffer and loop every character */
+ Cp = Name->Buffer;
+ for (i = 0; i < Name->Length; i += sizeof(WCHAR), Cp++)
+ {
+ /* Make sure we don't have a separator when we shouldn't */
+ ASSERT(AllowSeparators || (*Cp != OBJ_NAME_PATH_SEPARATOR));
+
+ /* Check what kind of char we have */
+ if (*Cp >= L'a')
+ {
+ /* In the lower case region... is it truly lower case? */
+ if (*Cp < L'z')
+ {
+ /* Yes! Calculate it ourselves! */
+ Value = *Cp - L'a' + L'A';
+ }
+ else
+ {
+ /* No, use the API */
+ Value = RtlUpcaseUnicodeChar(*Cp);
+ }
+ }
+ else
+ {
+ /* Reuse the char, it's already upcased */
+ Value = *Cp;
+ }
+
+ /* Multiply by a prime and add our value */
+ Hash *= 37;
+ Hash += Value;
+ }
+
+ /* Return the hash */
+ return Hash;
+}
+
+HCELL_INDEX
+NTAPI
+CmpFindSubKeyByHash(IN PHHIVE Hive,
+ IN PCM_KEY_FAST_INDEX FastIndex,
+ IN PUNICODE_STRING SearchName)
+{
+ ULONG HashKey, i;
+ PCM_INDEX FastEntry;
+
+ /* Make sure it's really a hash */
+ ASSERT(FastIndex->Signature == CM_KEY_HASH_LEAF);
+
+ /* Compute the hash key for the name */
+ HashKey = CmpComputeHashKey(0, SearchName, FALSE);
+
+ /* Loop all the entries */
+ for (i = 0; i < FastIndex->Count; i++)
+ {
+ /* Get the entry */
+ FastEntry = &FastIndex->List[i];
+
+ /* Compare the hash first */
+ if (FastEntry->HashKey == HashKey)
+ {
+ /* Go ahead for a full compare */
+ if (!(CmpDoCompareKeyName(Hive, SearchName, FastEntry->Cell)))
+ {
+ /* It matched, return the cell */
+ return FastEntry->Cell;
+ }
+ }
+ }
+
+ /* If we got here then we failed */
+ return HCELL_NIL;
+}
+
+HCELL_INDEX
+NTAPI
+CmpFindSubKeyByName(IN PHHIVE Hive,
+ IN PCM_KEY_NODE Parent,
+ IN PUNICODE_STRING SearchName)
+{
+ ULONG i;
+ PCM_KEY_INDEX IndexRoot;
+ HCELL_INDEX SubKey, CellToRelease;
+ ULONG Found;
+
+ /* Loop each storage type */
+ for (i = 0; i < Hive->StorageTypeCount; i++)
+ {
+ /* Make sure the parent node has subkeys */
+ if (Parent->SubKeyCounts[i])
+ {
+ /* Get the Index */
+ IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, Parent->SubKeyLists[i]);
+#if 0
+ /* Make sure we have one and that the cell is allocated */
+ ASSERT((IndexRoot == NULL) ||
+ HvIsCellAllocated(Hive, Parent->SubKeyLists[i]));
+#endif
+ /* Fail if we don't actually have an index root */
+ if (!IndexRoot) return HCELL_NIL;
+
+ /* Get the cell we'll need to release */
+ CellToRelease = Parent->SubKeyLists[i];
+
+ /* Check if this is another index root */
+ if (IndexRoot->Signature == CM_KEY_INDEX_ROOT)
+ {
+ /* Lookup the name in the root */
+ Found = CmpFindSubKeyInRoot(Hive,
+ IndexRoot,
+ SearchName,
+ &SubKey);
+
+ /* Release the previous cell */
+ ASSERT(CellToRelease != HCELL_NIL);
+ HvReleaseCell(Hive, CellToRelease);
+
+ /* Make sure we found something valid */
+ if (Found < 0) break;
+
+ /* Get the new Index Root and set the new cell to be released */
+ if (SubKey == HCELL_NIL) continue;
+ CellToRelease = SubKey;
+ IndexRoot = (PCM_KEY_INDEX)HvGetCell(Hive, SubKey);
+ }
+
+ /* Make sure the signature is what we expect it to be */
+ ASSERT((IndexRoot->Signature == CM_KEY_INDEX_LEAF) ||
+ (IndexRoot->Signature == CM_KEY_FAST_LEAF) ||
+ (IndexRoot->Signature == CM_KEY_HASH_LEAF));
+
+ /* Check if this isn't a hashed leaf */
+ if (IndexRoot->Signature != CM_KEY_HASH_LEAF)
+ {
+ /* Find the subkey in the leaf */
+ Found = CmpFindSubKeyInLeaf(Hive,
+ IndexRoot,
+ SearchName,
+ &SubKey);
+
+ /* Release the previous cell */
+ ASSERT(CellToRelease != HCELL_NIL);
+ HvReleaseCell(Hive, CellToRelease);
+
+ /* Make sure we found a valid index */
+ if (Found < 0) break;
+ }
+ else
+ {
+ /* Find the subkey in the hash */
+ SubKey = CmpFindSubKeyByHash(Hive,
+ (PCM_KEY_FAST_INDEX)IndexRoot,
+ SearchName);
+
+ /* Release the previous cell */
+ ASSERT(CellToRelease != HCELL_NIL);
+ HvReleaseCell(Hive, CellToRelease);
+ }
+
+ /* Make sure we got a valid subkey and return it */
+ if (SubKey != HCELL_NIL) return SubKey;
+ }
+ }
+
+ /* If we got here, then we failed */
+ return HCELL_NIL;
+}
Added: trunk/reactos/ntoskrnl/config/cmmapvw.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmmapvw.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmmapvw.c (added)
+++ trunk/reactos/ntoskrnl/config/cmmapvw.c Wed May 9 22:30:21 2007
@@ -1,0 +1,33 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmmapvw.c
+ * PURPOSE: Configuration Manager - Map-Viewed Hive Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+CmpInitHiveViewList(IN PCMHIVE Hive)
+{
+ /* Initialize the list heads */
+ InitializeListHead(&Hive->LRUViewListHead);
+ InitializeListHead(&Hive->PinViewListHead);
+
+ /* Reset data */
+ Hive->MappedViews = 0;
+ Hive->PinnedViews = 0;
+ Hive->UseCount = 0;
+}
+
Added: trunk/reactos/ntoskrnl/config/cmname.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmname.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmname.c (added)
+++ trunk/reactos/ntoskrnl/config/cmname.c Wed May 9 22:30:21 2007
@@ -1,0 +1,166 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmname.c
+ * PURPOSE: Configuration Manager - Name Management
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+LONG
+NTAPI
+CmpCompareCompressedName(IN PUNICODE_STRING SearchName,
+ IN PWCHAR CompressedName,
+ IN ULONG NameLength)
+{
+ WCHAR *p;
+ CHAR *pp;
+ WCHAR p1, p2;
+ USHORT SearchLength;
+ LONG Result;
+
+ /* Set the pointers and length and then loop */
+ p = SearchName->Buffer;
+ pp = (PCHAR)CompressedName;
+ SearchLength = (SearchName->Length / sizeof(WCHAR));
+ while ((SearchLength) && (NameLength))
+ {
+ /* Get the characters */
+ p1 = *p++;
+ p2 = (WCHAR)(*pp++);
+
+ /* Check if we have a direct match */
+ if (p1 != p2)
+ {
+ /* See if they match and return result if they don't */
+ Result = (LONG)RtlUpcaseUnicodeChar(p1) -
+ (LONG)RtlUpcaseUnicodeChar(p2);
+ if (Result) return Result;
+ }
+
+ /* Next chars */
+ SearchLength--;
+ NameLength--;
+ }
+
+ /* Return the difference directly */
+ return SearchLength - NameLength;
+}
+
+BOOLEAN
+NTAPI
+CmpFindNameInList(IN PHHIVE Hive,
+ IN PCHILD_LIST ChildList,
+ IN PUNICODE_STRING Name,
+ IN PULONG ChildIndex,
+ IN PHCELL_INDEX CellIndex)
+{
+ PCELL_DATA CellData;
+ HCELL_INDEX CellToRelease = HCELL_NIL;
+ ULONG i;
+ PCM_KEY_VALUE KeyValue;
+ LONG Result;
+ UNICODE_STRING SearchName;
+ BOOLEAN Success;
+
+ /* Make sure there's actually something on the list */
+ if (ChildList->Count != 0)
+ {
+ /* Get the cell data */
+ CellData = (PCELL_DATA)HvGetCell(Hive, ChildList->List);
+ if (!CellData)
+ {
+ /* Couldn't get the cell... tell the caller */
+ *CellIndex = HCELL_NIL;
+ return FALSE;
+ }
+
+ /* Now loop every entry */
+ for (i = 0; i < ChildList->Count; i++)
+ {
+ /* Check if we have a cell to release */
+ if (CellToRelease != HCELL_NIL)
+ {
+ /* Release it */
+ HvReleaseCell(Hive, CellToRelease);
+ CellToRelease = HCELL_NIL;
+ }
+
+ /* Get this value */
+ KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, CellData->u.KeyList[i]);
+ if (!KeyValue)
+ {
+ /* Return with no data found */
+ *CellIndex = HCELL_NIL;
+ Success = FALSE;
+ goto Return;
+ }
+
+ /* Save the cell to release */
+ CellToRelease = CellData->u.KeyList[i];
+
+ /* Check if it's a compressed value name */
+ if (KeyValue->Flags & VALUE_COMP_NAME)
+ {
+ /* Use the compressed name check */
+ Result = CmpCompareCompressedName(Name,
+ KeyValue->Name,
+ KeyValue->NameLength);
+ }
+ else
+ {
+ /* Setup the Unicode string */
+ SearchName.Length = KeyValue->NameLength;
+ SearchName.MaximumLength = SearchName.Length;
+ SearchName.Buffer = KeyValue->Name;
+ Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
+ }
+
+ /* Check if we found it */
+ if (!Result)
+ {
+ /* We did...return info to caller */
+ if (ChildIndex) *ChildIndex = i;
+ *CellIndex = CellData->u.KeyList[i];
+
+ /* Set success state */
+ Success = TRUE;
+ goto Return;
+ }
+ }
+
+ /* Got to the end of the list */
+ if (ChildIndex) *ChildIndex = i;
+ *CellIndex = HCELL_NIL;
+
+ /* Nothing found if we got here */
+ Success = TRUE;
+ goto Return;
+ }
+
+ /* Nothing found...check if the caller wanted more info */
+ ASSERT(ChildList->Count == 0);
+ if (ChildIndex) *ChildIndex = 0;
+ *CellIndex = HCELL_NIL;
+
+ /* Nothing found if we got here */
+ return TRUE;
+
+Return:
+ /* Release the first cell we got */
+ if (CellData) HvReleaseCell(Hive, ChildList->List);
+
+ /* Release the secondary one, if we have one */
+ if (CellToRelease) HvReleaseCell(Hive, CellToRelease);
+ return Success;
+}
Added: trunk/reactos/ntoskrnl/config/cmparse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmparse.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmparse.c (added)
+++ trunk/reactos/ntoskrnl/config/cmparse.c Wed May 9 22:30:21 2007
@@ -1,0 +1,75 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmparse.c
+ * PURPOSE: Configuration Manager - Object Manager Parse Interface
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+CmpGetNextName(IN OUT PUNICODE_STRING RemainingName,
+ OUT PUNICODE_STRING NextName,
+ OUT PBOOLEAN LastName)
+{
+ BOOLEAN NameValid = TRUE;
+
+ /* Check if there's nothing left in the name */
+ if (!(RemainingName->Buffer) ||
+ (!RemainingName->Length) ||
+ !(*RemainingName->Buffer))
+ {
+ /* Clear the next name and set this as last */
+ *LastName = TRUE;
+ NextName->Buffer = NULL;
+ NextName->Length = 0;
+ return TRUE;
+ }
+
+ /* Check if we have a path separator */
+ if (*RemainingName->Buffer == OBJ_NAME_PATH_SEPARATOR)
+ {
+ /* Skip it */
+ RemainingName->Buffer++;
+ RemainingName->Length -= sizeof(WCHAR);
+ RemainingName->MaximumLength -= sizeof(WCHAR);
+ }
+
+ /* Start loop at where the current buffer is */
+ NextName->Buffer = RemainingName->Buffer;
+ while (TRUE)
+ {
+ /* Break out if we ran out or hit a path separator */
+ if (!(RemainingName->Length) ||
+ (*RemainingName->Buffer == OBJ_NAME_PATH_SEPARATOR))
+ {
+ break;
+ }
+
+ /* Move to the next character */
+ RemainingName->Buffer++;
+ RemainingName->Length -= sizeof(WCHAR);
+ RemainingName->MaximumLength -= sizeof(WCHAR);
+ }
+
+ /* See how many chars we parsed and validate the length */
+ NextName->Length = (USHORT)((ULONG_PTR)RemainingName->Buffer -
+ (ULONG_PTR)NextName->Buffer);
+ if (NextName->Length > 512) NameValid = FALSE;
+ NextName->MaximumLength = NextName->Length;
+
+ /* If there's nothing left, we're last */
+ *LastName = !RemainingName->Length;
+ return NameValid;
+}
Added: trunk/reactos/ntoskrnl/config/cmsecach.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsecach.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsecach.c (added)
+++ trunk/reactos/ntoskrnl/config/cmsecach.c Wed May 9 22:30:21 2007
@@ -1,0 +1,38 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmsecach.c
+ * PURPOSE: Configuration Manager - Security Cache
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+CmpInitSecurityCache(IN PCMHIVE Hive)
+{
+ ULONG i;
+
+ /* Reset data */
+ Hive->SecurityCount = 0;
+ Hive->SecurityCacheSize = 0;
+ Hive->SecurityHitHint = -1;
+ Hive->SecurityCache = NULL;
+
+ /* Loop every security hash */
+ for (i = 0; i < 64; i++)
+ {
+ /* Initialize it */
+ InitializeListHead(&Hive->SecurityHash[i]);
+ }
+}
Added: trunk/reactos/ntoskrnl/config/cmvalue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmvalue.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmvalue.c (added)
+++ trunk/reactos/ntoskrnl/config/cmvalue.c Wed May 9 22:30:21 2007
@@ -1,0 +1,125 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/config/cmvalue.c
+ * PURPOSE: Configuration Manager - Cell Values
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include "ntoskrnl.h"
+#include "cm.h"
+#define NDEBUG
+#include "debug.h"
+
+/* GLOBALS *******************************************************************/
+
+/* FUNCTIONS *****************************************************************/
+
+HCELL_INDEX
+NTAPI
+CmpFindValueByName(IN PHHIVE Hive,
+ IN PCM_KEY_NODE KeyNode,
+ IN PUNICODE_STRING Name)
+{
+ HCELL_INDEX CellIndex;
+
+ /* Call the main function */
+ if (!CmpFindNameInList(Hive,
+ &KeyNode->ValueList,
+ Name,
+ NULL,
+ &CellIndex))
+ {
+ /* Santy check */
+ ASSERT(CellIndex == HCELL_NIL);
+ }
+
+ /* Return the index */
+ return CellIndex;
+}
+
+BOOLEAN
+NTAPI
+CmpGetValueData(IN PHHIVE Hive,
+ IN PCM_KEY_VALUE Value,
+ IN PULONG Length,
+ OUT PVOID *Buffer,
+ OUT PBOOLEAN BufferAllocated,
+ OUT PHCELL_INDEX CellToRelease)
+{
+ PAGED_CODE();
+
+ /* Sanity check */
+ ASSERT(Value->Signature == CM_KEY_VALUE_SIGNATURE);
+
+ /* Set failure defaults */
+ *BufferAllocated = FALSE;
+ *Buffer = NULL;
+ *CellToRelease = HCELL_NIL;
+
+ /* Check if this is a small key */
+ if (CmpIsKeyValueSmall(Length, Value->DataLength))
+ {
+ /* Return the data immediately */
+ *Buffer = &Value->Data;
+ return TRUE;
+ }
+
+ /* Check if this is a big cell */
+ if (CmpIsKeyValueBig(Hive, *Length))
+ {
+ /* FIXME: We don't support big cells */
+ DPRINT1("Unsupported cell type!\n");
+ while (TRUE);
+ }
+
+ /* Get the data from the cell */
+ *Buffer = HvGetCell(Hive, Value->Data);
+ if (!(*Buffer)) return FALSE;
+
+ /* Return success and the cell to be released */
+ *CellToRelease = Value->Data;
+ return TRUE;
+}
+
+PCELL_DATA
+NTAPI
+CmpValueToData(IN PHHIVE Hive,
+ IN PCM_KEY_VALUE Value,
+ OUT PULONG Length)
+{
+ PCELL_DATA Buffer;
+ BOOLEAN BufferAllocated;
+ HCELL_INDEX CellToRelease;
+ PAGED_CODE();
+
+ /* Sanity check */
+ ASSERT(Hive->ReleaseCellRoutine == NULL);
+
+ /* Get the actual data */
+ if (!CmpGetValueData(Hive,
+ Value,
+ Length,
+ (PVOID)&Buffer,
+ &BufferAllocated,
+ &CellToRelease))
+ {
+ /* We failed */
+ ASSERT(BufferAllocated == FALSE);
+ ASSERT(Buffer == NULL);
+ return NULL;
+ }
+
+ /* This should never happen!*/
+ if (BufferAllocated)
+ {
+ /* Free the buffer and bugcheck */
+ ExFreePool(Buffer);
+ KEBUGCHECKEX(REGISTRY_ERROR, 8, 0, (ULONG_PTR)Hive, (ULONG_PTR)Value);
+ }
+
+ /* Otherwise, return the cell data */
+ return Buffer;
+}
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Wed May 9 22:30:21 2007
@@ -83,14 +83,23 @@
<file>pin.c</file>
<file>view.c</file>
</directory>
+ <directory name="config">
+ <file>cmboot.c</file>
+ <file>cmcontrl.c</file>
+ <file>cmdata.c</file>
+ <file>cmindex.c</file>
+ <file>cmmapvw.c</file>
+ <file>cmname.c</file>
+ <file>cmparse.c</file>
+ <file>cmsecach.c</file>
+ <file>cmvalue.c</file>
+ </directory>
<directory name="cm">
<file>import.c</file>
<file>ntfunc.c</file>
<file>regfile.c</file>
<file>registry.c</file>
<file>regobj.c</file>
- <file>newcm.c</file>
- <file>cmdata.c</file>
</directory>
<directory name="dbgk">
<file>dbgkutil.c</file>