Implemented 'QueryName' method for key objects.
[reactos.git] / reactos / ntoskrnl / cm / cm.h
1 #ifndef __INCLUDE_CM_H
2 #define __INCLUDE_CM_H
3
4 #ifdef DBG
5 #define CHECKED 1
6 #else
7 #define CHECKED 0
8 #endif
9
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"
24
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"
31
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"
37
38 #define REG_BLOCK_SIZE 4096
39 #define REG_HBIN_DATA_OFFSET 32
40 #define REG_BIN_ID 0x6e696268
41 #define REG_INIT_BLOCK_LIST_SIZE 32
42 #define REG_INIT_HASH_TABLE_SIZE 3
43 #define REG_EXTEND_HASH_TABLE_SIZE 4
44 #define REG_VALUE_LIST_CELL_MULTIPLE 4
45 #define REG_KEY_CELL_ID 0x6b6e
46 #define REG_HASH_TABLE_BLOCK_ID 0x666c
47 #define REG_VALUE_CELL_ID 0x6b76
48 #define REG_HIVE_ID 0x66676572
49
50
51 // BLOCK_OFFSET = offset in file after header block
52 typedef ULONG BLOCK_OFFSET;
53
54 /* header for registry hive file : */
55 typedef struct _HIVE_HEADER
56 {
57 /* Hive identifier "regf" (0x66676572) */
58 ULONG BlockId;
59
60 /* Update counter */
61 ULONG UpdateCounter1;
62
63 /* Update counter */
64 ULONG UpdateCounter2;
65
66 /* When this hive file was last modified */
67 FILETIME DateModified;
68
69 /* Registry format version ? (1?) */
70 ULONG Unused3;
71
72 /* Registry format version ? (3?) */
73 ULONG Unused4;
74
75 /* Registry format version ? (0?) */
76 ULONG Unused5;
77
78 /* Registry format version ? (1?) */
79 ULONG Unused6;
80
81 /* Offset into file from the byte after the end of the base block.
82 If the hive is volatile, this is the actual pointer to the KEY_CELL */
83 BLOCK_OFFSET RootKeyCell;
84
85 /* Size of each hive block ? */
86 ULONG BlockSize;
87
88 /* (1?) */
89 ULONG Unused7;
90
91 /* Name of hive file */
92 WCHAR FileName[64];
93
94 /* ? */
95 ULONG Unused8[83];
96
97 /* Checksum of first 0x200 bytes */
98 ULONG Checksum;
99 } __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
100
101 typedef struct _HBIN
102 {
103 /* Bin identifier "hbin" (0x6E696268) */
104 ULONG BlockId;
105
106 /* Block offset of this bin */
107 BLOCK_OFFSET BlockOffset;
108
109 /* Size in bytes, multiple of the block size (4KB) */
110 ULONG BlockSize;
111
112 /* ? */
113 ULONG Unused1;
114
115 /* When this bin was last modified */
116 FILETIME DateModified;
117
118 /* ? */
119 ULONG Unused2;
120 } __attribute__((packed)) HBIN, *PHBIN;
121
122 typedef struct _CELL_HEADER
123 {
124 /* <0 if used, >0 if free */
125 LONG CellSize;
126 } __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
127
128 typedef struct _KEY_CELL
129 {
130 /* Size of this cell */
131 LONG CellSize;
132
133 /* Key cell identifier "kn" (0x6b6e) */
134 USHORT Id;
135
136 /* Flags */
137 USHORT Flags;
138
139 /* Time of last flush */
140 FILETIME LastWriteTime;
141
142 /* ? */
143 ULONG UnUsed1;
144
145 /* Block offset of parent key cell */
146 BLOCK_OFFSET ParentKeyOffset;
147
148 /* Count of sub keys for the key in this key cell */
149 ULONG NumberOfSubKeys;
150
151 /* ? */
152 ULONG UnUsed2;
153
154 /* Block offset of has table for FIXME: subkeys/values? */
155 BLOCK_OFFSET HashTableOffset;
156
157 /* ? */
158 ULONG UnUsed3;
159
160 /* Count of values contained in this key cell */
161 ULONG NumberOfValues;
162
163 /* Block offset of VALUE_LIST_CELL */
164 BLOCK_OFFSET ValuesOffset;
165
166 /* Block offset of security cell */
167 BLOCK_OFFSET SecurityKeyOffset;
168
169 /* Block offset of registry key class */
170 BLOCK_OFFSET ClassNameOffset;
171
172 /* ? */
173 ULONG Unused4[5];
174
175 /* Size in bytes of key name */
176 USHORT NameSize;
177
178 /* Size of class name in bytes */
179 USHORT ClassSize;
180
181 /* Name of key (not zero terminated) */
182 UCHAR Name[0];
183 } __attribute__((packed)) KEY_CELL, *PKEY_CELL;
184
185 /* KEY_CELL.Flags constants */
186 #define REG_KEY_ROOT_CELL 0x0C
187 #define REG_KEY_LINK_CELL 0x10
188 #define REG_KEY_NAME_PACKED 0x20
189
190
191 /*
192 * Hash record
193 *
194 * HashValue :
195 * packed name: four letters of value's name
196 * otherwise: Zero!
197 */
198 typedef struct _HASH_RECORD
199 {
200 BLOCK_OFFSET KeyOffset;
201 ULONG HashValue;
202 } __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
203
204 typedef struct _HASH_TABLE_CELL
205 {
206 LONG CellSize;
207 USHORT Id;
208 USHORT HashTableSize;
209 HASH_RECORD Table[0];
210 } __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
211
212
213 typedef struct _VALUE_LIST_CELL
214 {
215 LONG CellSize;
216 BLOCK_OFFSET Values[0];
217 } __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
218
219 typedef struct _VALUE_CELL
220 {
221 LONG CellSize;
222 USHORT Id; // "kv"
223 USHORT NameSize; // length of Name
224 LONG DataSize; // length of datas in the cell pointed by DataOffset
225 BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set
226 ULONG DataType;
227 USHORT Flags;
228 USHORT Unused1;
229 UCHAR Name[0]; /* warning : not zero terminated */
230 } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
231
232 /* VALUE_CELL.Flags constants */
233 #define REG_VALUE_NAME_PACKED 0x0001
234
235
236 typedef struct _DATA_CELL
237 {
238 LONG CellSize;
239 UCHAR Data[0];
240 } __attribute__((packed)) DATA_CELL, *PDATA_CELL;
241
242 typedef struct _REGISTRY_HIVE
243 {
244 LIST_ENTRY HiveList;
245 ULONG Flags;
246 UNICODE_STRING HiveFileName;
247 UNICODE_STRING LogFileName;
248 ULONG FileSize;
249 PHIVE_HEADER HiveHeader;
250 ULONG UpdateCounter;
251 ULONG BlockListSize;
252 PHBIN *BlockList;
253 ULONG FreeListSize;
254 ULONG FreeListMax;
255 PCELL_HEADER *FreeList;
256 BLOCK_OFFSET *FreeListOffset;
257 ERESOURCE HiveResource;
258
259 PULONG BitmapBuffer;
260 RTL_BITMAP DirtyBitMap;
261 BOOLEAN HiveDirty;
262 } REGISTRY_HIVE, *PREGISTRY_HIVE;
263
264 /* REGISTRY_HIVE.Flags constants */
265 /* When set, the hive uses pointers instead of offsets. */
266 #define HIVE_POINTER 0x00000001
267
268 /* When set, the hive is not backed by a file.
269 Therefore, it can not be flushed to disk. */
270 #define HIVE_NO_FILE 0x00000002
271
272 /* When set, a modified (dirty) hive is not synchronized automatically.
273 Explicit synchronization (save/flush) works. */
274 #define HIVE_NO_SYNCH 0x00000004
275
276 #define IsPointerHive(Hive) ((Hive)->Flags & HIVE_POINTER)
277 #define IsNoFileHive(Hive) ((Hive)->Flags & HIVE_NO_FILE)
278 #define IsNoSynchHive(Hive) ((Hive)->Flags & HIVE_NO_SYNCH)
279
280
281 #define IsFreeCell(Cell)(Cell->CellSize >= 0)
282 #define IsUsedCell(Cell)(Cell->CellSize < 0)
283
284
285 /* KEY_OBJECT.Flags */
286
287 /* When set, the key is scheduled for deletion, and all
288 attempts to access the key must not succeed */
289 #define KO_MARKED_FOR_DELETE 0x00000001
290
291
292 /* Type defining the Object Manager Key Object */
293 typedef struct _KEY_OBJECT
294 {
295 /* Fields used by the Object Manager */
296 CSHORT Type;
297 CSHORT Size;
298
299 /* Key flags */
300 ULONG Flags;
301
302 /* Key name */
303 UNICODE_STRING Name;
304
305 /* Registry hive the key belongs to */
306 PREGISTRY_HIVE RegistryHive;
307
308 /* Block offset of the key cell this key belongs in */
309 BLOCK_OFFSET BlockOffset;
310
311 /* KEY_CELL this key belong in */
312 PKEY_CELL KeyCell;
313
314 /* Link to the parent KEY_OBJECT for this key */
315 struct _KEY_OBJECT *ParentKey;
316
317 /* Subkeys loaded in SubKeys */
318 ULONG NumberOfSubKeys;
319
320 /* Space allocated in SubKeys */
321 ULONG SizeOfSubKeys;
322
323 /* List of subkeys loaded */
324 struct _KEY_OBJECT **SubKeys;
325 } KEY_OBJECT, *PKEY_OBJECT;
326
327 /* Bits 31-22 (top 10 bits) of the cell index is the directory index */
328 #define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
329 /* Bits 21-12 (middle 10 bits) of the cell index is the table index */
330 #define CmiTableIndex(Cellndex)(CellIndex & 0x003ff000)
331 /* Bits 11-0 (bottom 12 bits) of the cell index is the byte offset */
332 #define CmiByteOffset(Cellndex)(CellIndex & 0x00000fff)
333
334
335 extern BOOLEAN CmiDoVerify;
336 extern PREGISTRY_HIVE CmiVolatileHive;
337 extern POBJECT_TYPE CmiKeyType;
338 extern KSPIN_LOCK CmiKeyListLock;
339
340 extern LIST_ENTRY CmiHiveListHead;
341 extern ERESOURCE CmiHiveListLock;
342
343
344 VOID
345 CmiVerifyBinCell(PHBIN BinCell);
346 VOID
347 CmiVerifyKeyCell(PKEY_CELL KeyCell);
348 VOID
349 CmiVerifyRootKeyCell(PKEY_CELL RootKeyCell);
350 VOID
351 CmiVerifyKeyObject(PKEY_OBJECT KeyObject);
352 VOID
353 CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
354
355 #ifdef DBG
356 #define VERIFY_BIN_CELL CmiVerifyBinCell
357 #define VERIFY_KEY_CELL CmiVerifyKeyCell
358 #define VERIFY_ROOT_KEY_CELL CmiVerifyRootKeyCell
359 #define VERIFY_VALUE_CELL CmiVerifyValueCell
360 #define VERIFY_VALUE_LIST_CELL CmiVerifyValueListCell
361 #define VERIFY_KEY_OBJECT CmiVerifyKeyObject
362 #define VERIFY_REGISTRY_HIVE CmiVerifyRegistryHive
363 #else
364 #define VERIFY_BIN_CELL(x)
365 #define VERIFY_KEY_CELL(x)
366 #define VERIFY_ROOT_KEY_CELL(x)
367 #define VERIFY_VALUE_CELL(x)
368 #define VERIFY_VALUE_LIST_CELL(x)
369 #define VERIFY_KEY_OBJECT(x)
370 #define VERIFY_REGISTRY_HIVE(x)
371 #endif
372
373 NTSTATUS STDCALL
374 CmiObjectParse(IN PVOID ParsedObject,
375 OUT PVOID *NextObject,
376 IN PUNICODE_STRING FullPath,
377 IN OUT PWSTR *Path,
378 IN ULONG Attribute);
379
380 NTSTATUS STDCALL
381 CmiObjectCreate(PVOID ObjectBody,
382 PVOID Parent,
383 PWSTR RemainingPath,
384 POBJECT_ATTRIBUTES ObjectAttributes);
385
386 VOID STDCALL
387 CmiObjectDelete(PVOID DeletedObject);
388
389 NTSTATUS STDCALL
390 CmiObjectSecurity(PVOID ObjectBody,
391 SECURITY_OPERATION_CODE OperationCode,
392 SECURITY_INFORMATION SecurityInformation,
393 PSECURITY_DESCRIPTOR SecurityDescriptor,
394 PULONG BufferLength);
395
396 NTSTATUS STDCALL
397 CmiObjectQueryName (PVOID ObjectBody,
398 POBJECT_NAME_INFORMATION ObjectNameInfo,
399 ULONG Length,
400 PULONG ReturnLength);
401
402 NTSTATUS
403 CmiImportHiveBins(PREGISTRY_HIVE Hive,
404 PUCHAR ChunkPtr);
405
406 VOID
407 CmiFreeHiveBins(PREGISTRY_HIVE Hive);
408
409 NTSTATUS
410 CmiCreateHiveFreeCellList(PREGISTRY_HIVE Hive);
411
412 VOID
413 CmiFreeHiveFreeCellList(PREGISTRY_HIVE Hive);
414
415 NTSTATUS
416 CmiCreateHiveBitmap(PREGISTRY_HIVE Hive);
417
418
419 VOID
420 CmiAddKeyToList(IN PKEY_OBJECT ParentKey,
421 IN PKEY_OBJECT NewKey);
422
423 NTSTATUS
424 CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
425
426 PKEY_OBJECT
427 CmiScanKeyList(IN PKEY_OBJECT Parent,
428 IN PUNICODE_STRING KeyName,
429 IN ULONG Attributes);
430
431 NTSTATUS
432 CmiCreateVolatileHive(PREGISTRY_HIVE *RegistryHive);
433
434 NTSTATUS
435 CmiLoadHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
436 PUNICODE_STRING FileName,
437 ULONG Flags);
438
439 NTSTATUS
440 CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
441
442 NTSTATUS
443 CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
444
445 ULONG
446 CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
447 IN PKEY_CELL KeyCell);
448
449 ULONG
450 CmiGetMaxClassLength(IN PREGISTRY_HIVE RegistryHive,
451 IN PKEY_CELL KeyCell);
452
453 ULONG
454 CmiGetMaxValueNameLength(IN PREGISTRY_HIVE RegistryHive,
455 IN PKEY_CELL KeyCell);
456
457 ULONG
458 CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
459 IN PKEY_CELL KeyCell);
460
461 NTSTATUS
462 CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
463 IN PKEY_CELL KeyCell,
464 OUT PKEY_CELL *SubKeyCell,
465 OUT BLOCK_OFFSET *BlockOffset,
466 IN PUNICODE_STRING KeyName,
467 IN ACCESS_MASK DesiredAccess,
468 IN ULONG Attributes);
469
470 NTSTATUS
471 CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
472 IN PKEY_OBJECT Parent,
473 OUT PKEY_OBJECT SubKey,
474 IN PUNICODE_STRING SubKeyName,
475 IN ULONG TitleIndex,
476 IN PUNICODE_STRING Class,
477 IN ULONG CreateOptions);
478
479 NTSTATUS
480 CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
481 IN PKEY_OBJECT Parent,
482 IN PKEY_OBJECT SubKey);
483
484 NTSTATUS
485 CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
486 IN PKEY_CELL KeyCell,
487 IN PUNICODE_STRING ValueName,
488 OUT PVALUE_CELL *ValueCell,
489 OUT BLOCK_OFFSET *VBOffset);
490
491 NTSTATUS
492 CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
493 IN PKEY_CELL KeyCell,
494 IN ULONG Index,
495 OUT PVALUE_CELL *ValueCell);
496
497 NTSTATUS
498 CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
499 IN PKEY_CELL KeyCell,
500 IN PUNICODE_STRING ValueName,
501 OUT PVALUE_CELL *pValueCell,
502 OUT BLOCK_OFFSET *pVBOffset);
503
504 NTSTATUS
505 CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
506 IN PKEY_CELL KeyCell,
507 IN BLOCK_OFFSET KeyCellOffset,
508 IN PUNICODE_STRING ValueName);
509
510 NTSTATUS
511 CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
512 OUT PHASH_TABLE_CELL *HashBlock,
513 OUT BLOCK_OFFSET *HBOffset,
514 IN ULONG HashTableSize);
515
516 PKEY_CELL
517 CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
518 PHASH_TABLE_CELL HashBlock,
519 ULONG Index);
520
521 NTSTATUS
522 CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
523 PHASH_TABLE_CELL HashBlock,
524 PKEY_CELL NewKeyCell,
525 BLOCK_OFFSET NKBOffset);
526
527 NTSTATUS
528 CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
529 PHASH_TABLE_CELL HashBlock,
530 BLOCK_OFFSET NKBOffset);
531
532 NTSTATUS
533 CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
534 OUT PVALUE_CELL *ValueCell,
535 OUT BLOCK_OFFSET *VBOffset,
536 IN PUNICODE_STRING ValueName);
537
538 NTSTATUS
539 CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
540 PVALUE_CELL ValueCell,
541 BLOCK_OFFSET VBOffset);
542
543 NTSTATUS
544 CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
545 PVOID *Block,
546 LONG BlockSize,
547 BLOCK_OFFSET * pBlockOffset);
548
549 NTSTATUS
550 CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
551 PVOID Block,
552 BLOCK_OFFSET Offset);
553
554 PVOID
555 CmiGetBlock(PREGISTRY_HIVE RegistryHive,
556 BLOCK_OFFSET BlockOffset,
557 OUT PHBIN * ppBin);
558
559 VOID
560 CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
561 BLOCK_OFFSET BlockOffset);
562
563 VOID
564 CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive,
565 BLOCK_OFFSET BinOffset);
566
567 NTSTATUS
568 CmiAddFree(PREGISTRY_HIVE RegistryHive,
569 PCELL_HEADER FreeBlock,
570 BLOCK_OFFSET FreeOffset,
571 BOOLEAN MergeFreeBlocks);
572
573 NTSTATUS
574 CmiConnectHive(POBJECT_ATTRIBUTES KeyObjectAttributes,
575 PREGISTRY_HIVE RegistryHive);
576
577 NTSTATUS
578 CmiDisconnectHive (POBJECT_ATTRIBUTES KeyObjectAttributes,
579 PREGISTRY_HIVE *RegistryHive);
580
581 NTSTATUS
582 CmiInitHives(BOOLEAN SetupBoot);
583
584 ULONG
585 CmiGetPackedNameLength(IN PUNICODE_STRING Name,
586 OUT PBOOLEAN Packable);
587
588 BOOLEAN
589 CmiComparePackedNames(IN PUNICODE_STRING Name,
590 IN PCHAR NameBuffer,
591 IN USHORT NameBufferSize,
592 IN BOOLEAN NamePacked);
593
594 VOID
595 CmiCopyPackedName(PWCHAR NameBuffer,
596 PCHAR PackedNameBuffer,
597 ULONG PackedNameSize);
598
599 BOOLEAN
600 CmiCompareHash(PUNICODE_STRING KeyName,
601 PCHAR HashString);
602
603 BOOLEAN
604 CmiCompareHashI(PUNICODE_STRING KeyName,
605 PCHAR HashString);
606
607 BOOLEAN
608 CmiCompareKeyNames(PUNICODE_STRING KeyName,
609 PKEY_CELL KeyCell);
610
611 BOOLEAN
612 CmiCompareKeyNamesI(PUNICODE_STRING KeyName,
613 PKEY_CELL KeyCell);
614
615
616 VOID
617 CmiSyncHives(VOID);
618
619 #endif /*__INCLUDE_CM_H*/