69f6866583a4885b5af33adcd75b7a9a43d81b79
[reactos.git] / 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  SYSTEM_LOG_FILE                L"\\SystemRoot\\System32\\Config\\SYSTEM.log"
25 #define  SOFTWARE_REG_FILE              L"\\SystemRoot\\System32\\Config\\SOFTWARE"
26 #define  USER_REG_FILE                  L"\\SystemRoot\\System32\\Config\\DEFAULT"
27 #define  SAM_REG_FILE                   L"\\SystemRoot\\System32\\Config\\SAM"
28 #define  SEC_REG_FILE                   L"\\SystemRoot\\System32\\Config\\SECURITY"
29
30 #define  REG_SYSTEM_FILE_NAME           L"\\SYSTEM"
31 #define  REG_SOFTWARE_FILE_NAME         L"\\SOFTWARE"
32 #define  REG_USER_FILE_NAME             L"\\DEFAULT"
33 #define  REG_SAM_FILE_NAME              L"\\SAM"
34 #define  REG_SEC_FILE_NAME              L"\\SECURITY"
35
36 #define  REG_BLOCK_SIZE                4096
37 #define  REG_HBIN_DATA_OFFSET          32
38 #define  REG_BIN_ID                    0x6e696268
39 #define  REG_INIT_BLOCK_LIST_SIZE      32
40 #define  REG_INIT_HASH_TABLE_SIZE      3
41 #define  REG_EXTEND_HASH_TABLE_SIZE    4
42 #define  REG_VALUE_LIST_CELL_MULTIPLE  4
43 #define  REG_KEY_CELL_ID               0x6b6e
44 #define  REG_HASH_TABLE_BLOCK_ID       0x666c
45 #define  REG_VALUE_CELL_ID             0x6b76
46 #define  REG_HIVE_ID                   0x66676572
47
48 #define  REGISTRY_FILE_MAGIC    "REGEDIT4"
49
50 #define  REG_MACHINE_STD_HANDLE_NAME  "HKEY_LOCAL_MACHINE"
51 #define  REG_CLASSES_STD_HANDLE_NAME  "HKEY_CLASSES_ROOT"
52 #define  REG_USERS_STD_HANDLE_NAME    "HKEY_USERS"
53 #define  REG_USER_STD_HANDLE_NAME     "HKEY_CURRENT_USER"
54 #define  REG_CONFIG_STD_HANDLE_NAME   "HKEY_CURRENT_CONFIG"
55 #define  REG_DYN_STD_HANDLE_NAME      "HKEY_DYN_DATA"
56 #define  MAX_REG_STD_HANDLE_NAME      19
57
58 // BLOCK_OFFSET = offset in file after header block
59 typedef ULONG BLOCK_OFFSET;
60
61 /* header for registry hive file : */
62 typedef struct _HIVE_HEADER
63 {
64   /* Hive identifier "regf" (0x66676572) */
65   ULONG  BlockId;
66
67   /* Update counter */
68   ULONG  UpdateCounter1;
69
70   /* Update counter */
71   ULONG  UpdateCounter2;
72
73   /* When this hive file was last modified */
74   FILETIME  DateModified;
75
76   /* Registry format version ? (1?) */
77   ULONG  Unused3;
78
79   /* Registry format version ? (3?) */
80   ULONG  Unused4;
81
82   /* Registry format version ? (0?) */
83   ULONG  Unused5;
84
85   /* Registry format version ? (1?) */
86   ULONG  Unused6;
87
88   /* Offset into file from the byte after the end of the base block.
89      If the hive is volatile, this is the actual pointer to the KEY_CELL */
90   BLOCK_OFFSET  RootKeyCell;
91
92   /* Size of each hive block ? */
93   ULONG  BlockSize;
94
95   /* (1?) */
96   ULONG  Unused7;
97
98   /* Name of hive file */
99   WCHAR  FileName[64];
100
101   /* ? */
102   ULONG  Unused8[83];
103
104   /* Checksum of first 0x200 bytes */
105   ULONG  Checksum;
106 } __attribute__((packed)) HIVE_HEADER, *PHIVE_HEADER;
107
108 typedef struct _HBIN
109 {
110   /* Bin identifier "hbin" (0x6E696268) */
111   ULONG  BlockId;
112
113   /* Block offset of this bin */
114   BLOCK_OFFSET  BlockOffset;
115
116   /* Size in bytes, multiple of the block size (4KB) */
117   ULONG  BlockSize;
118
119   /* ? */
120   ULONG  Unused1;
121
122   /* When this bin was last modified */
123   FILETIME  DateModified;
124
125   /* ? */
126   ULONG  Unused2;
127 } __attribute__((packed)) HBIN, *PHBIN;
128
129 typedef struct _CELL_HEADER
130 {
131   /* <0 if used, >0 if free */
132   LONG  CellSize;
133 } __attribute__((packed)) CELL_HEADER, *PCELL_HEADER;
134
135 typedef struct _KEY_CELL
136 {
137   /* Size of this cell */
138   LONG  CellSize;
139
140   /* Key cell identifier "kn" (0x6b6e) */
141   USHORT  Id;
142
143   /* ? */
144   USHORT  Type;
145
146   /* Time of last flush */
147   FILETIME  LastWriteTime;
148
149   /* ? */
150   ULONG  UnUsed1;
151
152   /* Block offset of parent key cell */
153   BLOCK_OFFSET  ParentKeyOffset;
154
155   /* Count of sub keys for the key in this key cell */
156   ULONG  NumberOfSubKeys;
157
158   /* ? */
159   ULONG  UnUsed2;
160
161   /* Block offset of has table for FIXME: subkeys/values? */
162   BLOCK_OFFSET  HashTableOffset;
163
164   /* ? */
165   ULONG  UnUsed3;
166
167   /* Count of values contained in this key cell */
168   ULONG  NumberOfValues;
169
170   /* Block offset of VALUE_LIST_CELL */
171   BLOCK_OFFSET  ValuesOffset;
172
173   /* Block offset of security cell */
174   BLOCK_OFFSET  SecurityKeyOffset;
175
176   /* Block offset of registry key class */
177   BLOCK_OFFSET  ClassNameOffset;
178
179   /* ? */
180   ULONG  Unused4[5];
181
182   /* Size in bytes of key name */
183   USHORT NameSize;
184
185   /* Size of class name in bytes */
186   USHORT ClassSize;
187
188   /* Name of key (not zero terminated) */
189   UCHAR  Name[0];
190 } __attribute__((packed)) KEY_CELL, *PKEY_CELL;
191
192 /* KEY_CELL.Type constants */
193 #define  REG_LINK_KEY_CELL_TYPE        0x10
194 #define  REG_KEY_CELL_TYPE             0x20
195 #define  REG_ROOT_KEY_CELL_TYPE        0x2c
196
197
198 // hash record :
199 // HashValue=four letters of value's name
200 typedef struct _HASH_RECORD
201 {
202   BLOCK_OFFSET  KeyOffset;
203   ULONG  HashValue;
204 } __attribute__((packed)) HASH_RECORD, *PHASH_RECORD;
205
206 typedef struct _HASH_TABLE_CELL
207 {
208   LONG  CellSize;
209   USHORT  Id;
210   USHORT  HashTableSize;
211   HASH_RECORD  Table[0];
212 } __attribute__((packed)) HASH_TABLE_CELL, *PHASH_TABLE_CELL;
213
214 typedef struct _VALUE_LIST_CELL
215 {
216   LONG  CellSize;
217   BLOCK_OFFSET  Values[0];
218 } __attribute__((packed)) VALUE_LIST_CELL, *PVALUE_LIST_CELL;
219
220 typedef struct _VALUE_CELL
221 {
222   LONG  CellSize;
223   USHORT Id;    // "kv"
224   USHORT NameSize;      // length of Name
225   LONG  DataSize;       // length of datas in the cell pointed by DataOffset
226   BLOCK_OFFSET  DataOffset;// datas are here if high bit of DataSize is set
227   ULONG  DataType;
228   USHORT Flags;
229   USHORT Unused1;
230   UCHAR  Name[0]; /* warning : not zero terminated */
231 } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
232
233 /* VALUE_CELL.Flags constants */
234 #define REG_VALUE_NAME_PACKED             0x0001
235
236
237 typedef struct _DATA_CELL
238 {
239   LONG  CellSize;
240   UCHAR  Data[0];
241 } __attribute__((packed)) DATA_CELL, *PDATA_CELL;
242
243 typedef struct _REGISTRY_HIVE
244 {
245   LIST_ENTRY  HiveList;
246   ULONG  Flags;
247   UNICODE_STRING  HiveFileName;
248   UNICODE_STRING  LogFileName;
249   ULONG  FileSize;
250   PHIVE_HEADER  HiveHeader;
251   ULONG  UpdateCounter;
252   ULONG  BlockListSize;
253   PHBIN  *BlockList;
254   ULONG  FreeListSize;
255   ULONG  FreeListMax;
256   PCELL_HEADER *FreeList;
257   BLOCK_OFFSET *FreeListOffset;
258   ERESOURCE  HiveResource;
259
260   PULONG BitmapBuffer;
261   RTL_BITMAP  DirtyBitMap;
262   BOOLEAN  HiveDirty;
263 } REGISTRY_HIVE, *PREGISTRY_HIVE;
264
265 /* REGISTRY_HIVE.Flags constants */
266 /* When set, the hive is volatile. It will not be sync'ed to disk. */
267 #define HIVE_VOLATILE   0x00000001
268 /* When set, the hive uses pointers instead of offsets. */
269 #define HIVE_POINTER    0x00000002
270 /* When set, the hive is temporary. It will not be sync'ed to disk. */
271 #define HIVE_TEMPORARY  0x00000004
272
273 #define IsVolatileHive(Hive)(Hive->Flags & HIVE_VOLATILE)
274 #define IsPointerHive(Hive)(Hive->Flags & HIVE_POINTER)
275 #define IsTemporaryHive(Hive)(Hive->Flags & HIVE_TEMPORARY)
276
277
278 #define IsFreeCell(Cell)(Cell->CellSize >= 0)
279 #define IsUsedCell(Cell)(Cell->CellSize < 0)
280
281
282 /* KEY_OBJECT.Flags */
283
284 /* When set, the key is scheduled for deletion, and all
285    attempts to access the key must not succeed */
286 #define KO_MARKED_FOR_DELETE              0x00000001
287
288
289 /* Type defining the Object Manager Key Object */
290 typedef struct _KEY_OBJECT
291 {
292   /* Fields used by the Object Manager */
293   CSHORT Type;
294   CSHORT Size;
295
296   /* Key flags */
297   ULONG Flags;
298
299   /* Length of Name */
300   USHORT NameSize;
301
302   /* Name of key */
303   PCHAR 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 VOID
397 CmiAddKeyToList(PKEY_OBJECT ParentKey,
398   IN PKEY_OBJECT  NewKey);
399
400 NTSTATUS
401 CmiRemoveKeyFromList(IN PKEY_OBJECT  NewKey);
402
403 PKEY_OBJECT  CmiScanKeyList(IN PKEY_OBJECT Parent,
404   IN PCHAR  KeyNameBuf,
405   IN ULONG  Attributes);
406
407 NTSTATUS
408 CmiCreateRegistryHive(PWSTR Filename,
409   PREGISTRY_HIVE *RegistryHive,
410   BOOLEAN CreateNew);
411
412 NTSTATUS
413 CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive);
414
415 NTSTATUS
416 CmiFlushRegistryHive(PREGISTRY_HIVE RegistryHive);
417
418 ULONG
419 CmiGetMaxNameLength(IN PREGISTRY_HIVE  RegistryHive,
420   IN PKEY_CELL  KeyCell);
421
422 ULONG
423 CmiGetMaxClassLength(IN PREGISTRY_HIVE  RegistryHive,
424   IN PKEY_CELL  KeyCell);
425
426 ULONG
427 CmiGetMaxValueNameLength(IN PREGISTRY_HIVE  RegistryHive,
428   IN PKEY_CELL  KeyCell);
429
430 ULONG
431 CmiGetMaxValueDataLength(IN PREGISTRY_HIVE  RegistryHive,
432   IN PKEY_CELL  KeyCell);
433
434 NTSTATUS
435 CmiScanForSubKey(IN PREGISTRY_HIVE  RegistryHive,
436   IN PKEY_CELL  KeyCell,
437   OUT PKEY_CELL  *SubKeyCell,
438   OUT BLOCK_OFFSET *BlockOffset,
439   IN PCHAR  KeyName,
440   IN ACCESS_MASK  DesiredAccess,
441   IN ULONG Attributes);
442
443 NTSTATUS
444 CmiAddSubKey(IN PREGISTRY_HIVE  RegistryHive,
445   IN PKEY_OBJECT Parent,
446   OUT PKEY_OBJECT SubKey,
447   IN PWSTR  NewSubKeyName,
448   IN USHORT  NewSubKeyNameSize,
449   IN ULONG  TitleIndex,
450   IN PUNICODE_STRING  Class,
451   IN ULONG  CreateOptions);
452
453 NTSTATUS
454 CmiRemoveSubKey(IN PREGISTRY_HIVE RegistryHive,
455                 IN PKEY_OBJECT Parent,
456                 IN PKEY_OBJECT SubKey);
457
458 NTSTATUS
459 CmiScanKeyForValue(IN PREGISTRY_HIVE  RegistryHive,
460   IN PKEY_CELL  KeyCell,
461   IN PUNICODE_STRING  ValueName,
462   OUT PVALUE_CELL  *ValueCell,
463   OUT BLOCK_OFFSET *VBOffset);
464
465 NTSTATUS
466 CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE  RegistryHive,
467   IN PKEY_CELL  KeyCell,
468   IN ULONG  Index,
469   OUT PVALUE_CELL  *ValueCell);
470
471 NTSTATUS
472 CmiAddValueToKey(IN PREGISTRY_HIVE  RegistryHive,
473   IN PKEY_CELL  KeyCell,
474   IN PUNICODE_STRING ValueName,
475   OUT PVALUE_CELL *pValueCell,
476   OUT BLOCK_OFFSET *pVBOffset);
477
478 NTSTATUS
479 CmiDeleteValueFromKey(IN PREGISTRY_HIVE  RegistryHive,
480                       IN PKEY_CELL  KeyCell,
481                       IN BLOCK_OFFSET KeyCellOffset,
482                       IN PUNICODE_STRING ValueName);
483
484 NTSTATUS
485 CmiAllocateHashTableBlock(IN PREGISTRY_HIVE  RegistryHive,
486   OUT PHASH_TABLE_CELL  *HashBlock,
487   OUT BLOCK_OFFSET  *HBOffset,
488   IN ULONG  HashTableSize);
489
490 PKEY_CELL
491 CmiGetKeyFromHashByIndex(PREGISTRY_HIVE RegistryHive,
492 PHASH_TABLE_CELL  HashBlock,
493 ULONG  Index);
494
495 NTSTATUS
496 CmiAddKeyToHashTable(PREGISTRY_HIVE  RegistryHive,
497   PHASH_TABLE_CELL  HashBlock,
498   PKEY_CELL  NewKeyCell,
499   BLOCK_OFFSET  NKBOffset);
500
501 NTSTATUS
502 CmiRemoveKeyFromHashTable(PREGISTRY_HIVE RegistryHive,
503                           PHASH_TABLE_CELL HashBlock,
504                           BLOCK_OFFSET NKBOffset);
505
506 NTSTATUS
507 CmiAllocateValueCell(IN PREGISTRY_HIVE  RegistryHive,
508   OUT PVALUE_CELL  *ValueCell,
509   OUT BLOCK_OFFSET  *VBOffset,
510   IN PUNICODE_STRING ValueName);
511
512 NTSTATUS
513 CmiDestroyValueCell(PREGISTRY_HIVE  RegistryHive,
514   PVALUE_CELL  ValueCell,
515   BLOCK_OFFSET  VBOffset);
516
517 NTSTATUS
518 CmiAllocateBlock(PREGISTRY_HIVE  RegistryHive,
519   PVOID  *Block,
520   LONG  BlockSize,
521         BLOCK_OFFSET * pBlockOffset);
522
523 NTSTATUS
524 CmiDestroyBlock(PREGISTRY_HIVE  RegistryHive,
525   PVOID  Block,
526   BLOCK_OFFSET Offset);
527
528 PVOID
529 CmiGetBlock(PREGISTRY_HIVE  RegistryHive,
530             BLOCK_OFFSET  BlockOffset,
531             OUT PHBIN * ppBin);
532
533 VOID
534 CmiMarkBlockDirty(PREGISTRY_HIVE RegistryHive,
535                   BLOCK_OFFSET BlockOffset);
536
537 VOID
538 CmiMarkBinDirty(PREGISTRY_HIVE RegistryHive,
539                 BLOCK_OFFSET BinOffset);
540
541 NTSTATUS
542 CmiAddFree(PREGISTRY_HIVE  RegistryHive,
543            PCELL_HEADER FreeBlock,
544            BLOCK_OFFSET FreeOffset,
545            BOOLEAN MergeFreeBlocks);
546
547 NTSTATUS
548 CmiConnectHive(PREGISTRY_HIVE RegistryHive,
549                PUNICODE_STRING KeyName);
550
551 NTSTATUS
552 CmiInitHives(BOOLEAN SetupBoot);
553
554 ULONG
555 CmiGetPackedNameLength(IN PUNICODE_STRING Name,
556                        OUT PBOOLEAN Packable);
557
558 BOOLEAN
559 CmiComparePackedNames(IN PUNICODE_STRING Name,
560                       IN PCHAR NameBuffer,
561                       IN USHORT NameBufferSize,
562                       IN BOOLEAN NamePacked);
563
564 VOID
565 CmiCopyPackedName(PWCHAR NameBuffer,
566                   PCHAR PackedNameBuffer,
567                   ULONG PackedNameSize);
568
569 VOID
570 CmiSyncHives(VOID);
571
572 #endif /*__INCLUDE_CM_H*/