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