10 #define REG_ROOT_KEY_NAME L"\\Registry"
11 #define REG_MACHINE_KEY_NAME L"\\Registry\\Machine"
12 #define REG_HARDWARE_KEY_NAME L"\\Registry\\Machine\\HARDWARE"
13 #define REG_DESCRIPTION_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION"
14 #define REG_DEVICEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP"
15 #define REG_RESOURCEMAP_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP"
16 #define REG_CLASSES_KEY_NAME L"\\Registry\\Machine\\Software\\Classes"
17 #define REG_SYSTEM_KEY_NAME L"\\Registry\\Machine\\SYSTEM"
18 #define REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\SOFTWARE"
19 #define REG_SAM_KEY_NAME L"\\Registry\\Machine\\SAM"
20 #define REG_SEC_KEY_NAME L"\\Registry\\Machine\\SECURITY"
21 #define REG_USER_KEY_NAME L"\\Registry\\User"
22 #define REG_DEFAULT_USER_KEY_NAME L"\\Registry\\User\\.Default"
23 #define REG_CURRENT_USER_KEY_NAME L"\\Registry\\User\\CurrentUser"
25 #define SYSTEM_REG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM"
26 #define SYSTEM_LOG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM.log"
27 #define SOFTWARE_REG_FILE L"\\SystemRoot\\System32\\Config\\SOFTWARE"
28 #define DEFAULT_USER_REG_FILE L"\\SystemRoot\\System32\\Config\\DEFAULT"
29 #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
30 #define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY"
32 #define REG_SYSTEM_FILE_NAME L"\\system"
33 #define REG_SOFTWARE_FILE_NAME L"\\software"
34 #define REG_DEFAULT_USER_FILE_NAME L"\\default"
35 #define REG_SAM_FILE_NAME L"\\sam"
36 #define REG_SEC_FILE_NAME L"\\security"
38 #define REG_BLOCK_SIZE 4096
39 #define REG_HBIN_DATA_OFFSET 32
40 #define REG_INIT_BLOCK_LIST_SIZE 32
41 #define REG_INIT_HASH_TABLE_SIZE 3
42 #define REG_EXTEND_HASH_TABLE_SIZE 4
43 #define REG_VALUE_LIST_CELL_MULTIPLE 4
45 #define REG_HIVE_ID 0x66676572
46 #define REG_BIN_ID 0x6e696268
47 #define REG_KEY_CELL_ID 0x6b6e
48 #define REG_HASH_TABLE_CELL_ID 0x666c
49 #define REG_VALUE_CELL_ID 0x6b76
50 #define REG_SECURITY_CELL_ID 0x6b73
53 // BLOCK_OFFSET = offset in file after header block
54 typedef ULONG BLOCK_OFFSET
, *PBLOCK_OFFSET
;
58 /* header for registry hive file : */
59 typedef struct _HIVE_HEADER
61 /* Hive identifier "regf" (0x66676572) */
70 /* When this hive file was last modified */
71 LARGE_INTEGER DateModified
;
73 /* Registry format version ? (1?) */
76 /* Registry format version ? (3?) */
79 /* Registry format version ? (0?) */
82 /* Registry format version ? (1?) */
85 /* Offset into file from the byte after the end of the base block.
86 If the hive is volatile, this is the actual pointer to the KEY_CELL */
87 BLOCK_OFFSET RootKeyOffset
;
89 /* Size of each hive block ? */
95 /* Name of hive file */
101 /* Checksum of first 0x200 bytes */
103 } HIVE_HEADER
, *PHIVE_HEADER
;
105 typedef struct _BIN_HEADER
107 /* Bin identifier "hbin" (0x6E696268) */
110 /* Block offset of this bin */
111 BLOCK_OFFSET BinOffset
;
113 /* Size in bytes, multiple of the block size (4KB) */
119 /* When this bin was last modified */
120 LARGE_INTEGER DateModified
;
126 typedef struct _CELL_HEADER
128 /* <0 if used, >0 if free */
130 } CELL_HEADER
, *PCELL_HEADER
;
132 typedef struct _KEY_CELL
134 /* Size of this cell */
137 /* Key cell identifier "kn" (0x6b6e) */
143 /* Time of last flush */
144 LARGE_INTEGER LastWriteTime
;
149 /* Block offset of parent key cell */
150 BLOCK_OFFSET ParentKeyOffset
;
152 /* Count of sub keys for the key in this key cell */
153 ULONG NumberOfSubKeys
;
158 /* Block offset of has table for FIXME: subkeys/values? */
159 BLOCK_OFFSET HashTableOffset
;
164 /* Count of values contained in this key cell */
165 ULONG NumberOfValues
;
167 /* Block offset of VALUE_LIST_CELL */
168 BLOCK_OFFSET ValueListOffset
;
170 /* Block offset of security cell */
171 BLOCK_OFFSET SecurityKeyOffset
;
173 /* Block offset of registry key class */
174 BLOCK_OFFSET ClassNameOffset
;
179 /* Size in bytes of key name */
182 /* Size of class name in bytes */
185 /* Name of key (not zero terminated) */
187 } KEY_CELL
, *PKEY_CELL
;
189 /* KEY_CELL.Flags constants */
190 #define REG_KEY_ROOT_CELL 0x0C
191 #define REG_KEY_LINK_CELL 0x10
192 #define REG_KEY_NAME_PACKED 0x20
198 * packed name: four letters of value's name
201 typedef struct _HASH_RECORD
203 BLOCK_OFFSET KeyOffset
;
205 } HASH_RECORD
, *PHASH_RECORD
;
207 typedef struct _HASH_TABLE_CELL
211 USHORT HashTableSize
;
212 HASH_RECORD Table
[0];
213 } HASH_TABLE_CELL
, *PHASH_TABLE_CELL
;
216 typedef struct _VALUE_LIST_CELL
219 BLOCK_OFFSET ValueOffset
[0];
220 } VALUE_LIST_CELL
, *PVALUE_LIST_CELL
;
222 typedef struct _VALUE_CELL
226 USHORT NameSize
; // length of Name
227 ULONG DataSize
; // length of datas in the cell pointed by DataOffset
228 BLOCK_OFFSET DataOffset
;// datas are here if high bit of DataSize is set
232 UCHAR Name
[0]; /* warning : not zero terminated */
233 } VALUE_CELL
, *PVALUE_CELL
;
235 /* VALUE_CELL.Flags constants */
236 #define REG_VALUE_NAME_PACKED 0x0001
238 /* VALUE_CELL.DataSize mask constants */
239 #define REG_DATA_SIZE_MASK 0x7FFFFFFF
240 #define REG_DATA_IN_OFFSET 0x80000000
243 typedef struct _SECURITY_CELL
248 BLOCK_OFFSET PrevSecurityCell
;
249 BLOCK_OFFSET NextSecurityCell
;
253 } SECURITY_CELL
, *PSECURITY_CELL
;
256 typedef struct _DATA_CELL
260 } DATA_CELL
, *PDATA_CELL
;
265 typedef struct _BLOCK_LIST_ENTRY
269 } BLOCK_LIST_ENTRY
, *PBLOCK_LIST_ENTRY
;
272 typedef struct _REGISTRY_HIVE
276 UNICODE_STRING HiveFileName
;
277 UNICODE_STRING LogFileName
;
279 PHIVE_HEADER HiveHeader
;
282 PBLOCK_LIST_ENTRY BlockList
;
285 PCELL_HEADER
*FreeList
;
286 BLOCK_OFFSET
*FreeListOffset
;
288 PSECURITY_CELL RootSecurityCell
;
291 RTL_BITMAP DirtyBitMap
;
293 } REGISTRY_HIVE
, *PREGISTRY_HIVE
;
295 /* REGISTRY_HIVE.Flags constants */
296 /* When set, the hive uses pointers instead of offsets. */
297 #define HIVE_POINTER 0x00000001
299 /* When set, the hive is not backed by a file.
300 Therefore, it can not be flushed to disk. */
301 #define HIVE_NO_FILE 0x00000002
303 /* When set, a modified (dirty) hive is not synchronized automatically.
304 Explicit synchronization (save/flush) works. */
305 #define HIVE_NO_SYNCH 0x00000004
307 #define IsPointerHive(Hive) ((Hive)->Flags & HIVE_POINTER)
308 #define IsNoFileHive(Hive) ((Hive)->Flags & HIVE_NO_FILE)
309 #define IsNoSynchHive(Hive) ((Hive)->Flags & HIVE_NO_SYNCH)
312 #define IsFreeCell(Cell)(Cell->CellSize >= 0)
313 #define IsUsedCell(Cell)(Cell->CellSize < 0)
316 /* KEY_OBJECT.Flags */
318 /* When set, the key is scheduled for deletion, and all
319 attempts to access the key must not succeed */
320 #define KO_MARKED_FOR_DELETE 0x00000001
323 /* Type defining the Object Manager Key Object */
324 typedef struct _KEY_OBJECT
326 /* Fields used by the Object Manager */
336 /* Registry hive the key belongs to */
337 PREGISTRY_HIVE RegistryHive
;
339 /* Block offset of the key cell this key belongs in */
340 BLOCK_OFFSET KeyCellOffset
;
342 /* KEY_CELL this key belong in */
345 /* Link to the parent KEY_OBJECT for this key */
346 struct _KEY_OBJECT
*ParentKey
;
348 /* Subkeys loaded in SubKeys */
349 ULONG NumberOfSubKeys
;
351 /* Space allocated in SubKeys */
354 /* List of subkeys loaded */
355 struct _KEY_OBJECT
**SubKeys
;
356 } KEY_OBJECT
, *PKEY_OBJECT
;
358 /* Bits 31-22 (top 10 bits) of the cell index is the directory index */
359 #define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
360 /* Bits 21-12 (middle 10 bits) of the cell index is the table index */
361 #define CmiTableIndex(Cellndex)(CellIndex & 0x003ff000)
362 /* Bits 11-0 (bottom 12 bits) of the cell index is the byte offset */
363 #define CmiByteOffset(Cellndex)(CellIndex & 0x00000fff)
366 extern BOOLEAN CmiDoVerify
;
367 extern PREGISTRY_HIVE CmiVolatileHive
;
368 extern POBJECT_TYPE CmiKeyType
;
369 extern KSPIN_LOCK CmiKeyListLock
;
371 extern LIST_ENTRY CmiHiveListHead
;
373 extern ERESOURCE CmiRegistryLock
;
375 /* Registry Callback Function */
376 typedef NTSTATUS (*PEX_CALLBACK_FUNCTION
) (
377 IN PVOID CallbackContext
,
383 CmiVerifyBinHeader(PHBIN BinHeader
);
385 CmiVerifyKeyCell(PKEY_CELL KeyCell
);
387 CmiVerifyRootKeyCell(PKEY_CELL RootKeyCell
);
389 CmiVerifyKeyObject(PKEY_OBJECT KeyObject
);
391 CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive
);
394 #define VERIFY_BIN_HEADER CmiVerifyBinHeader
395 #define VERIFY_KEY_CELL CmiVerifyKeyCell
396 #define VERIFY_ROOT_KEY_CELL CmiVerifyRootKeyCell
397 #define VERIFY_VALUE_CELL CmiVerifyValueCell
398 #define VERIFY_VALUE_LIST_CELL CmiVerifyValueListCell
399 #define VERIFY_KEY_OBJECT CmiVerifyKeyObject
400 #define VERIFY_REGISTRY_HIVE CmiVerifyRegistryHive
402 #define VERIFY_BIN_HEADER(x)
403 #define VERIFY_KEY_CELL(x)
404 #define VERIFY_ROOT_KEY_CELL(x)
405 #define VERIFY_VALUE_CELL(x)
406 #define VERIFY_VALUE_LIST_CELL(x)
407 #define VERIFY_KEY_OBJECT(x)
408 #define VERIFY_REGISTRY_HIVE(x)
412 CmRegisterCallback(IN PEX_CALLBACK_FUNCTION Function
,
414 IN OUT PLARGE_INTEGER Cookie
418 CmUnRegisterCallback(IN LARGE_INTEGER Cookie
);
421 CmiObjectParse(IN PVOID ParsedObject
,
422 OUT PVOID
*NextObject
,
423 IN PUNICODE_STRING FullPath
,
428 CmiObjectCreate(PVOID ObjectBody
,
431 POBJECT_ATTRIBUTES ObjectAttributes
);
434 CmiObjectDelete(PVOID DeletedObject
);
437 CmiObjectSecurity(PVOID ObjectBody
,
438 SECURITY_OPERATION_CODE OperationCode
,
439 SECURITY_INFORMATION SecurityInformation
,
440 PSECURITY_DESCRIPTOR SecurityDescriptor
,
441 PULONG BufferLength
);
444 CmiObjectQueryName (PVOID ObjectBody
,
445 POBJECT_NAME_INFORMATION ObjectNameInfo
,
447 PULONG ReturnLength
);
450 CmiImportHiveBins(PREGISTRY_HIVE Hive
,
454 CmiFreeHiveBins(PREGISTRY_HIVE Hive
);
457 CmiCreateHiveFreeCellList(PREGISTRY_HIVE Hive
);
460 CmiFreeHiveFreeCellList(PREGISTRY_HIVE Hive
);
463 CmiCreateHiveBitmap(PREGISTRY_HIVE Hive
);
467 CmiAddKeyToList(IN PKEY_OBJECT ParentKey
,
468 IN PKEY_OBJECT NewKey
);
471 CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey
);
474 CmiScanKeyList(IN PKEY_OBJECT Parent
,
475 IN PUNICODE_STRING KeyName
,
476 IN ULONG Attributes
);
479 CmiCreateVolatileHive(PREGISTRY_HIVE
*RegistryHive
);
482 CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes
,
483 PUNICODE_STRING FileName
,
487 CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive
);
490 CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive
);
493 CmiGetNumberOfSubKeys(PKEY_OBJECT KeyObject
);
496 CmiGetMaxNameLength(IN PKEY_OBJECT KeyObject
);
499 CmiGetMaxClassLength(IN PKEY_OBJECT KeyObject
);
502 CmiGetMaxValueNameLength(IN PREGISTRY_HIVE RegistryHive
,
503 IN PKEY_CELL KeyCell
);
506 CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive
,
507 IN PKEY_CELL KeyCell
);
510 CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive
,
511 IN PKEY_CELL KeyCell
,
512 OUT PKEY_CELL
*SubKeyCell
,
513 OUT BLOCK_OFFSET
*BlockOffset
,
514 IN PUNICODE_STRING KeyName
,
515 IN ACCESS_MASK DesiredAccess
,
516 IN ULONG Attributes
);
519 CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive
,
520 IN PKEY_OBJECT ParentKey
,
521 OUT PKEY_OBJECT SubKey
,
522 IN PUNICODE_STRING SubKeyName
,
524 IN PUNICODE_STRING Class
,
525 IN ULONG CreateOptions
);
528 CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive
,
529 IN PKEY_OBJECT Parent
,
530 IN PKEY_OBJECT SubKey
);
533 CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive
,
534 IN PKEY_CELL KeyCell
,
535 IN PUNICODE_STRING ValueName
,
536 OUT PVALUE_CELL
*ValueCell
,
537 OUT BLOCK_OFFSET
*VBOffset
);
540 CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive
,
541 IN PKEY_CELL KeyCell
,
543 OUT PVALUE_CELL
*ValueCell
);
546 CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive
,
547 IN PKEY_CELL KeyCell
,
548 IN BLOCK_OFFSET KeyCellOffset
,
549 IN PUNICODE_STRING ValueName
,
550 OUT PVALUE_CELL
*pValueCell
,
551 OUT BLOCK_OFFSET
*pValueCellOffset
);
554 CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive
,
555 IN PKEY_CELL KeyCell
,
556 IN BLOCK_OFFSET KeyCellOffset
,
557 IN PUNICODE_STRING ValueName
);
560 CmiAllocateHashTableCell(IN PREGISTRY_HIVE RegistryHive
,
561 OUT PHASH_TABLE_CELL
*HashBlock
,
562 OUT BLOCK_OFFSET
*HBOffset
,
563 IN ULONG HashTableSize
);
566 CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive
,
567 PHASH_TABLE_CELL HashBlock
,
571 CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive
,
572 PHASH_TABLE_CELL HashCell
,
573 BLOCK_OFFSET HashCellOffset
,
574 PKEY_CELL NewKeyCell
,
575 BLOCK_OFFSET NKBOffset
);
578 CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive
,
579 PHASH_TABLE_CELL HashBlock
,
580 BLOCK_OFFSET NKBOffset
);
583 CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive
,
584 OUT PVALUE_CELL
*ValueCell
,
585 OUT BLOCK_OFFSET
*VBOffset
,
586 IN PUNICODE_STRING ValueName
);
589 CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive
,
590 PVALUE_CELL ValueCell
,
591 BLOCK_OFFSET VBOffset
);
594 CmiAllocateCell(PREGISTRY_HIVE RegistryHive
,
597 BLOCK_OFFSET
*CellOffset
);
600 CmiDestroyCell(PREGISTRY_HIVE RegistryHive
,
602 BLOCK_OFFSET CellOffset
);
605 CmiGetBin (PREGISTRY_HIVE RegistryHive
,
606 BLOCK_OFFSET CellOffset
);
609 CmiGetCell (PREGISTRY_HIVE RegistryHive
,
610 BLOCK_OFFSET CellOffset
,
614 CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive
,
615 BLOCK_OFFSET BlockOffset
);
618 CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive
,
619 BLOCK_OFFSET BinOffset
);
622 CmiAddFree(PREGISTRY_HIVE RegistryHive
,
623 PCELL_HEADER FreeBlock
,
624 BLOCK_OFFSET FreeOffset
,
625 BOOLEAN MergeFreeBlocks
);
628 CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes
,
629 PREGISTRY_HIVE RegistryHive
);
632 CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes
,
633 PREGISTRY_HIVE
*RegistryHive
);
636 CmiInitHives(BOOLEAN SetupBoot
);
639 CmiGetPackedNameLength(IN PUNICODE_STRING Name
,
640 OUT PBOOLEAN Packable
);
643 CmiComparePackedNames(IN PUNICODE_STRING Name
,
645 IN USHORT NameBufferSize
,
646 IN BOOLEAN NamePacked
);
649 CmiCopyPackedName(PWCHAR NameBuffer
,
650 PCHAR PackedNameBuffer
,
651 ULONG PackedNameSize
);
654 CmiCompareHash(PUNICODE_STRING KeyName
,
658 CmiCompareHashI(PUNICODE_STRING KeyName
,
662 CmiCompareKeyNames(PUNICODE_STRING KeyName
,
666 CmiCompareKeyNamesI(PUNICODE_STRING KeyName
,
675 CmiCreateTempHive(PREGISTRY_HIVE
*RegistryHive
);
678 CmiCopyKey (PREGISTRY_HIVE DstHive
,
679 PKEY_CELL DstKeyCell
,
680 PREGISTRY_HIVE SrcHive
,
681 PKEY_CELL SrcKeyCell
);
684 CmiSaveTempHive (PREGISTRY_HIVE Hive
,
687 #endif /*__INCLUDE_CM_H*/