MmCreateMdl(): Zero the allocated 'Mdl' memory
[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  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*/