New bins should be flushed properly.
[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_USERS_KEY_NAME L"\\Registry\\User"
22 #define REG_USER_KEY_NAME L"\\Registry\\User\\CurrentUser"
23 #define SYSTEM_REG_FILE L"\\SystemRoot\\System32\\Config\\SYSTEM"
24 #define SOFTWARE_REG_FILE L"\\SystemRoot\\System32\\Config\\SOFTWARE"
25 #define USER_REG_FILE L"\\SystemRoot\\System32\\Config\\DEFAULT"
26 #define SAM_REG_FILE L"\\SystemRoot\\System32\\Config\\SAM"
27 #define SEC_REG_FILE L"\\SystemRoot\\System32\\Config\\SECURITY"
28
29 #define REG_SYSTEM_FILE_NAME L"\\SYSTEM"
30 #define REG_SOFTWARE_FILE_NAME L"\\SOFTWARE"
31 #define REG_USER_FILE_NAME L"\\DEFAULT"
32 #define REG_SAM_FILE_NAME L"\\SAM"
33 #define REG_SEC_FILE_NAME L"\\SECURITY"
34
35 #define REG_BLOCK_SIZE 4096
36 #define REG_HBIN_DATA_OFFSET 32
37 #define REG_BIN_ID 0x6e696268
38 #define REG_INIT_BLOCK_LIST_SIZE 32
39 #define REG_INIT_HASH_TABLE_SIZE 3
40 #define REG_EXTEND_HASH_TABLE_SIZE 4
41 #define REG_VALUE_LIST_CELL_MULTIPLE 4
42 #define REG_KEY_CELL_ID 0x6b6e
43 #define REG_HASH_TABLE_BLOCK_ID 0x666c
44 #define REG_VALUE_CELL_ID 0x6b76
45 #define REG_HIVE_ID 0x66676572
46
47 #define REGISTRY_FILE_MAGIC "REGEDIT4"
48
49 #define REG_MACHINE_STD_HANDLE_NAME "HKEY_LOCAL_MACHINE"
50 #define REG_CLASSES_STD_HANDLE_NAME "HKEY_CLASSES_ROOT"
51 #define REG_USERS_STD_HANDLE_NAME "HKEY_USERS"
52 #define REG_USER_STD_HANDLE_NAME "HKEY_CURRENT_USER"
53 #define REG_CONFIG_STD_HANDLE_NAME "HKEY_CURRENT_CONFIG"
54 #define REG_DYN_STD_HANDLE_NAME "HKEY_DYN_DATA"
55 #define MAX_REG_STD_HANDLE_NAME 19
56
57 // BLOCK_OFFSET = offset in file after header block
58 typedef ULONG BLOCK_OFFSET;
59
60 /* header for registry hive file : */
61 typedef struct _HIVE_HEADER
62 {
63 /* Hive identifier "regf" (0x66676572) */
64 ULONG BlockId;
65
66 /* File version ? */
67 ULONG Version;
68
69 /* File version ? - same as Version */
70 ULONG VersionOld;
71
72 /* When this hive file was last modified */
73 FILETIME DateModified;
74
75 /* Registry format version ? (1?) */
76 ULONG Unused3;
77
78 /* Registry format version ? (3?) */
79 ULONG Unused4;
80
81 /* Registry format version ? (0?) */
82 ULONG Unused5;
83
84 /* Registry format version ? (1?) */
85 ULONG Unused6;
86
87 /* Offset into file from the byte after the end of the base block.
88 If the hive is volatile, this is the actual pointer to the KEY_CELL */
89 BLOCK_OFFSET RootKeyCell;
90
91 /* Size of each hive block ? */
92 ULONG BlockSize;
93
94 /* (1?) */
95 ULONG Unused7;
96
97 /* Name of hive file */
98 WCHAR FileName[64];
99
100 /* ? */
101 ULONG Unused8[83];
102
103 /* Checksum of first 0x200 bytes */
104 ULONG Checksum;
105 } __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
106
107 typedef struct _HBIN
108 {
109 /* Bin identifier "hbin" (0x6E696268) */
110 ULONG BlockId;
111
112 /* Block offset of this bin */
113 BLOCK_OFFSET BlockOffset;
114
115 /* Size in bytes, multiple of the block size (4KB) */
116 ULONG BlockSize;
117
118 /* ? */
119 ULONG Unused1;
120
121 /* When this bin was last modified */
122 FILETIME DateModified;
123
124 /* ? */
125 ULONG Unused2;
126 } __attribute__((packed)) HBIN, *PHBIN;
127
128 typedef struct _CELL_HEADER
129 {
130 /* <0 if used, >0 if free */
131 LONG CellSize;
132 } __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
133
134 typedef struct _KEY_CELL
135 {
136 /* Size of this cell */
137 LONG CellSize;
138
139 /* Key cell identifier "kn" (0x6b6e) */
140 USHORT Id;
141
142 /* ? */
143 USHORT Type;
144
145 /* Time of last flush */
146 FILETIME LastWriteTime;
147
148 /* ? */
149 ULONG UnUsed1;
150
151 /* Block offset of parent key cell */
152 BLOCK_OFFSET ParentKeyOffset;
153
154 /* Count of sub keys for the key in this key cell */
155 ULONG NumberOfSubKeys;
156
157 /* ? */
158 ULONG UnUsed2;
159
160 /* Block offset of has table for FIXME: subkeys/values? */
161 BLOCK_OFFSET HashTableOffset;
162
163 /* ? */
164 ULONG UnUsed3;
165
166 /* Count of values contained in this key cell */
167 ULONG NumberOfValues;
168
169 /* Block offset of VALUE_LIST_CELL */
170 BLOCK_OFFSET ValuesOffset;
171
172 /* Block offset of security cell */
173 BLOCK_OFFSET SecurityKeyOffset;
174
175 /* Block offset of registry key class */
176 BLOCK_OFFSET ClassNameOffset;
177
178 /* ? */
179 ULONG Unused4[5];
180
181 /* Size in bytes of key name */
182 USHORT NameSize;
183
184 /* Size of class name in bytes */
185 USHORT ClassSize;
186
187 /* Name of key (not zero terminated) */
188 UCHAR Name[0];
189 } __attribute__((packed)) KEY_CELL, *PKEY_CELL;
190
191 /* KEY_CELL.Type constants */
192 #define REG_LINK_KEY_CELL_TYPE 0x10
193 #define REG_KEY_CELL_TYPE 0x20
194 #define REG_ROOT_KEY_CELL_TYPE 0x2c
195
196
197 // hash record :
198 // HashValue=four letters of value's name
199 typedef struct _HASH_RECORD
200 {
201 BLOCK_OFFSET KeyOffset;
202 ULONG HashValue;
203 } __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
204
205 typedef struct _HASH_TABLE_CELL
206 {
207 LONG CellSize;
208 USHORT Id;
209 USHORT HashTableSize;
210 HASH_RECORD Table[0];
211 } __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
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 BlockListSize;
251 PHBIN *BlockList;
252 ULONG FreeListSize;
253 ULONG FreeListMax;
254 PCELL_HEADER *FreeList;
255 BLOCK_OFFSET *FreeListOffset;
256 ERESOURCE HiveResource;
257
258 RTL_BITMAP DirtyBitMap;
259 BOOLEAN HiveDirty;
260 } REGISTRY_HIVE, *PREGISTRY_HIVE;
261
262 /* REGISTRY_HIVE.Flags constants */
263 #define HIVE_VOLATILE 0x00000001
264
265 #define IsVolatileHive(Hive)(Hive->Flags & HIVE_VOLATILE)
266 #define IsPermanentHive(Hive)(!(Hive->Flags & HIVE_VOLATILE))
267
268 #define IsFreeCell(Cell)(Cell->CellSize >= 0)
269 #define IsUsedCell(Cell)(Cell->CellSize < 0)
270
271
272 /* KEY_OBJECT.Flags */
273
274 /* When set, the key is scheduled for deletion, and all
275 attempts to access the key must not succeed */
276 #define KO_MARKED_FOR_DELETE 0x00000001
277
278
279 /* Type defining the Object Manager Key Object */
280 typedef struct _KEY_OBJECT
281 {
282 /* Fields used by the Object Manager */
283 CSHORT Type;
284 CSHORT Size;
285
286 /* Key flags */
287 ULONG Flags;
288
289 /* Length of Name */
290 USHORT NameSize;
291
292 /* Name of key */
293 PCHAR Name;
294
295 /* Registry hive the key belongs to */
296 PREGISTRY_HIVE RegistryHive;
297
298 /* Block offset of the key cell this key belongs in */
299 BLOCK_OFFSET BlockOffset;
300
301 /* KEY_CELL this key belong in */
302 PKEY_CELL KeyCell;
303
304 /* Link to the parent KEY_OBJECT for this key */
305 struct _KEY_OBJECT *ParentKey;
306
307 /* Subkeys loaded in SubKeys */
308 ULONG NumberOfSubKeys;
309
310 /* Space allocated in SubKeys */
311 ULONG SizeOfSubKeys;
312
313 /* List of subkeys loaded */
314 struct _KEY_OBJECT **SubKeys;
315 } KEY_OBJECT, *PKEY_OBJECT;
316
317 /* Bits 31-22 (top 10 bits) of the cell index is the directory index */
318 #define CmiDirectoryIndex(CellIndex)(CellIndex & 0xffc000000)
319 /* Bits 21-12 (middle 10 bits) of the cell index is the table index */
320 #define CmiTableIndex(Cellndex)(CellIndex & 0x003ff000)
321 /* Bits 11-0 (bottom 12 bits) of the cell index is the byte offset */
322 #define CmiByteOffset(Cellndex)(CellIndex & 0x00000fff)
323
324
325 extern BOOLEAN CmiDoVerify;
326 extern PREGISTRY_HIVE CmiVolatileHive;
327 extern POBJECT_TYPE CmiKeyType;
328 extern KSPIN_LOCK CmiKeyListLock;
329
330 extern LIST_ENTRY CmiHiveListHead;
331 extern ERESOURCE CmiHiveListLock;
332
333
334 VOID
335 CmiVerifyBinCell(PHBIN BinCell);
336 VOID
337 CmiVerifyKeyCell(PKEY_CELL KeyCell);
338 VOID
339 CmiVerifyRootKeyCell(PKEY_CELL RootKeyCell);
340 VOID
341 CmiVerifyKeyObject(PKEY_OBJECT KeyObject);
342 VOID
343 CmiVerifyRegistryHive(PREGISTRY_HIVE RegistryHive);
344
345 #ifdef DBG
346 #define VERIFY_BIN_CELL CmiVerifyBinCell
347 #define VERIFY_KEY_CELL CmiVerifyKeyCell
348 #define VERIFY_ROOT_KEY_CELL CmiVerifyRootKeyCell
349 #define VERIFY_VALUE_CELL CmiVerifyValueCell
350 #define VERIFY_VALUE_LIST_CELL CmiVerifyValueListCell
351 #define VERIFY_KEY_OBJECT CmiVerifyKeyObject
352 #define VERIFY_REGISTRY_HIVE CmiVerifyRegistryHive
353 #else
354 #define VERIFY_BIN_CELL(x)
355 #define VERIFY_KEY_CELL(x)
356 #define VERIFY_ROOT_KEY_CELL(x)
357 #define VERIFY_VALUE_CELL(x)
358 #define VERIFY_VALUE_LIST_CELL(x)
359 #define VERIFY_KEY_OBJECT(x)
360 #define VERIFY_REGISTRY_HIVE(x)
361 #endif
362
363 NTSTATUS STDCALL
364 CmiObjectParse(IN PVOID ParsedObject,
365 OUT PVOID *NextObject,
366 IN PUNICODE_STRING FullPath,
367 IN OUT PWSTR *Path,
368 IN ULONG Attribute);
369
370 NTSTATUS STDCALL
371 CmiObjectCreate(PVOID ObjectBody,
372 PVOID Parent,
373 PWSTR RemainingPath,
374 struct _OBJECT_ATTRIBUTES* ObjectAttributes);
375
376 VOID STDCALL
377 CmiObjectDelete(PVOID DeletedObject);
378
379 VOID
380 CmiAddKeyToList(PKEY_OBJECT ParentKey,
381 IN PKEY_OBJECT NewKey);
382
383 NTSTATUS
384 CmiRemoveKeyFromList(IN PKEY_OBJECT NewKey);
385
386 PKEY_OBJECT CmiScanKeyList(IN PKEY_OBJECT Parent,
387 IN PCHAR KeyNameBuf,
388 IN ULONG Attributes);
389
390 NTSTATUS
391 CmiCreateRegistryHive(PWSTR Filename,
392 PREGISTRY_HIVE *RegistryHive,
393 BOOLEAN CreateNew);
394
395 NTSTATUS
396 CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
397
398 NTSTATUS
399 CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
400
401 ULONG
402 CmiGetMaxNameLength(IN PREGISTRY_HIVE RegistryHive,
403 IN PKEY_CELL KeyCell);
404
405 ULONG
406 CmiGetMaxClassLength(IN PREGISTRY_HIVE RegistryHive,
407 IN PKEY_CELL KeyCell);
408
409 ULONG
410 CmiGetMaxValueNameLength(IN PREGISTRY_HIVE RegistryHive,
411 IN PKEY_CELL KeyCell);
412
413 ULONG
414 CmiGetMaxValueDataLength(IN PREGISTRY_HIVE RegistryHive,
415 IN PKEY_CELL KeyCell);
416
417 NTSTATUS
418 CmiScanForSubKey(IN PREGISTRY_HIVE RegistryHive,
419 IN PKEY_CELL KeyCell,
420 OUT PKEY_CELL *SubKeyCell,
421 OUT BLOCK_OFFSET *BlockOffset,
422 IN PCHAR KeyName,
423 IN ACCESS_MASK DesiredAccess,
424 IN ULONG Attributes);
425
426 NTSTATUS
427 CmiAddSubKey(IN PREGISTRY_HIVE RegistryHive,
428 IN PKEY_OBJECT Parent,
429 OUT PKEY_OBJECT SubKey,
430 IN PWSTR NewSubKeyName,
431 IN USHORT NewSubKeyNameSize,
432 IN ULONG TitleIndex,
433 IN PUNICODE_STRING Class,
434 IN ULONG CreateOptions);
435
436 NTSTATUS
437 CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
438 IN PKEY_OBJECT Parent,
439 IN PKEY_OBJECT SubKey);
440
441 NTSTATUS
442 CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
443 IN PKEY_CELL KeyCell,
444 IN PUNICODE_STRING ValueName,
445 OUT PVALUE_CELL *ValueCell,
446 OUT BLOCK_OFFSET *VBOffset);
447
448 NTSTATUS
449 CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
450 IN PKEY_CELL KeyCell,
451 IN ULONG Index,
452 OUT PVALUE_CELL *ValueCell);
453
454 NTSTATUS
455 CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
456 IN PKEY_CELL KeyCell,
457 IN PUNICODE_STRING ValueName,
458 OUT PVALUE_CELL *pValueCell,
459 OUT BLOCK_OFFSET *pVBOffset);
460
461 NTSTATUS
462 CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
463 IN PKEY_CELL KeyCell,
464 IN BLOCK_OFFSET KeyCellOffset,
465 IN PUNICODE_STRING ValueName);
466
467 NTSTATUS
468 CmiAllocateHashTableBlock(IN PREGISTRY_HIVE RegistryHive,
469 OUT PHASH_TABLE_CELL *HashBlock,
470 OUT BLOCK_OFFSET *HBOffset,
471 IN ULONG HashTableSize);
472
473 PKEY_CELL
474 CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
475 PHASH_TABLE_CELL HashBlock,
476 ULONG Index);
477
478 NTSTATUS
479 CmiAddKeyToHashTable(PREGISTRY_HIVE RegistryHive,
480 PHASH_TABLE_CELL HashBlock,
481 PKEY_CELL NewKeyCell,
482 BLOCK_OFFSET NKBOffset);
483
484 NTSTATUS
485 CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
486 PHASH_TABLE_CELL HashBlock,
487 BLOCK_OFFSET NKBOffset);
488
489 NTSTATUS
490 CmiAllocateValueCell(IN PREGISTRY_HIVE RegistryHive,
491 OUT PVALUE_CELL *ValueCell,
492 OUT BLOCK_OFFSET *VBOffset,
493 IN PUNICODE_STRING ValueName);
494
495 NTSTATUS
496 CmiDestroyValueCell(PREGISTRY_HIVE RegistryHive,
497 PVALUE_CELL ValueCell,
498 BLOCK_OFFSET VBOffset);
499
500 NTSTATUS
501 CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
502 PVOID *Block,
503 LONG BlockSize,
504 BLOCK_OFFSET * pBlockOffset);
505
506 NTSTATUS
507 CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
508 PVOID Block,
509 BLOCK_OFFSET Offset);
510
511 PVOID
512 CmiGetBlock(PREGISTRY_HIVE RegistryHive,
513 BLOCK_OFFSET BlockOffset,
514 OUT PHBIN * ppBin);
515
516 VOID
517 CmiLockBlock(PREGISTRY_HIVE RegistryHive,
518 PVOID Block);
519
520 VOID
521 CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
522 PVOID Block);
523
524 VOID
525 CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
526 BLOCK_OFFSET BlockOffset);
527
528 VOID
529 CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive,
530 BLOCK_OFFSET BinOffset);
531
532 NTSTATUS
533 CmiAddFree(PREGISTRY_HIVE RegistryHive,
534 PCELL_HEADER FreeBlock,
535 BLOCK_OFFSET FreeOffset,
536 BOOLEAN MergeFreeBlocks);
537
538 NTSTATUS
539 CmiInitHives(BOOLEAN SetUpBoot);
540
541 ULONG
542 CmiGetPackedNameLength(IN PUNICODE_STRING Name,
543 OUT PBOOLEAN Packable);
544
545 BOOLEAN
546 CmiComparePackedNames(IN PUNICODE_STRING Name,
547 IN PCHAR NameBuffer,
548 IN USHORT NameBufferSize,
549 IN BOOLEAN NamePacked);
550
551 VOID
552 CmiCopyPackedName(PWCHAR NameBuffer,
553 PCHAR PackedNameBuffer,
554 ULONG PackedNameSize);
555
556 VOID
557 CmiSyncHives(VOID);
558
559 #endif /*__INCLUDE_CM_H*/