[CMLIB]: Implement CmpFreeSecurityDescriptor. See r70609.
[reactos.git] / reactos / lib / cmlib / cmlib.h
1 /*
2 * PROJECT: Registry manipulation library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * COPYRIGHT: Copyright 2005 Filip Navara <navaraf@reactos.org>
5 * Copyright 2001 - 2005 Eric Kohl
6 */
7
8 #ifndef _CMLIB_H_
9 #define _CMLIB_H_
10
11 //
12 // Debug support switch
13 //
14 #define _CMLIB_DEBUG_ 1
15
16 #ifdef CMLIB_HOST
17 #include <typedefs.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 // NTDDI_xxx versions we allude to in the library (see psdk/sdkddkver.h)
22 #define NTDDI_WS03SP4 0x05020400
23 #define NTDDI_WIN6 0x06000000
24 #define NTDDI_LONGHORN NTDDI_WIN6
25 #define NTDDI_VISTA NTDDI_WIN6
26 #define NTDDI_WIN7 0x06010000
27
28 #define NTDDI_VERSION NTDDI_WS03SP4 // This is the ReactOS NT kernel version
29
30 /* C_ASSERT Definition */
31 #define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
32
33 #ifdef _WIN32
34 #define strncasecmp _strnicmp
35 #define strcasecmp _stricmp
36 #endif // _WIN32
37
38 #if (!defined(_MSC_VER) || (_MSC_VER < 1500))
39 #define _In_
40 #define _Out_
41 #define _Inout_
42 #define _In_opt_
43 #define _In_range_(x, y)
44 #endif
45
46 #define __drv_aliasesMem
47
48 #ifndef min
49 #define min(a, b) (((a) < (b)) ? (a) : (b))
50 #endif
51
52 // #ifndef max
53 // #define max(a, b) (((a) > (b)) ? (a) : (b))
54 // #endif
55
56 // Definitions copied from <ntstatus.h>
57 // We only want to include host headers, so we define them manually
58 #define STATUS_SUCCESS ((NTSTATUS)0x00000000)
59 #define STATUS_NOT_IMPLEMENTED ((NTSTATUS)0xC0000002)
60 #define STATUS_NO_MEMORY ((NTSTATUS)0xC0000017)
61 #define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009A)
62 #define STATUS_REGISTRY_CORRUPT ((NTSTATUS)0xC000014C)
63 #define STATUS_NOT_REGISTRY_FILE ((NTSTATUS)0xC000015C)
64 #define STATUS_REGISTRY_RECOVERED ((NTSTATUS)0x40000009)
65
66 #define REG_OPTION_VOLATILE 1
67 #define OBJ_CASE_INSENSITIVE 0x00000040L
68 #define USHORT_MAX USHRT_MAX
69
70 #define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
71 #define UNICODE_NULL ((WCHAR)0)
72
73 VOID NTAPI
74 KeQuerySystemTime(
75 OUT PLARGE_INTEGER CurrentTime);
76
77 WCHAR NTAPI
78 RtlUpcaseUnicodeChar(
79 IN WCHAR Source);
80
81 VOID NTAPI
82 RtlInitializeBitMap(
83 IN PRTL_BITMAP BitMapHeader,
84 IN PULONG BitMapBuffer,
85 IN ULONG SizeOfBitMap);
86
87 ULONG NTAPI
88 RtlFindSetBits(
89 IN PRTL_BITMAP BitMapHeader,
90 IN ULONG NumberToFind,
91 IN ULONG HintIndex);
92
93 VOID NTAPI
94 RtlSetBits(
95 IN PRTL_BITMAP BitMapHeader,
96 IN ULONG StartingIndex,
97 IN ULONG NumberToSet);
98
99 VOID NTAPI
100 RtlClearAllBits(
101 IN PRTL_BITMAP BitMapHeader);
102
103 #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP) / 32]) >> ((BP) % 32)) & 0x1)
104 #define UNREFERENCED_PARAMETER(P) {(P)=(P);}
105
106 #define PKTHREAD PVOID
107 #define PKGUARDED_MUTEX PVOID
108 #define PERESOURCE PVOID
109 #define PFILE_OBJECT PVOID
110 #define PKEVENT PVOID
111 #define PWORK_QUEUE_ITEM PVOID
112 #define EX_PUSH_LOCK PULONG_PTR
113
114 // Definitions copied from <ntifs.h>
115 // We only want to include host headers, so we define them manually
116
117 typedef USHORT SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
118
119 typedef struct _SECURITY_DESCRIPTOR_RELATIVE
120 {
121 UCHAR Revision;
122 UCHAR Sbz1;
123 SECURITY_DESCRIPTOR_CONTROL Control;
124 ULONG Owner;
125 ULONG Group;
126 ULONG Sacl;
127 ULONG Dacl;
128 } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
129
130 #define CMLTRACE(x, ...)
131 #undef PAGED_CODE
132 #define PAGED_CODE()
133 #define REGISTRY_ERROR ((ULONG)0x00000051L)
134 #else
135 //
136 // Debug/Tracing support
137 //
138 #if _CMLIB_DEBUG_
139 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
140 #define CMLTRACE DbgPrintEx
141 #else
142 #define CMLTRACE(x, ...) \
143 if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__)
144 #endif
145 #else
146 #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__)
147 #endif
148
149 #include <ntdef.h>
150 #include <ntifs.h>
151 #include <bugcodes.h>
152 #undef PAGED_CODE
153 #define PAGED_CODE()
154
155 /* Prevent inclusion of Windows headers through <wine/unicode.h> */
156 #define _WINDEF_
157 #define _WINBASE_
158 #define _WINNLS_
159 #endif
160
161
162 //
163 // These define the Debug Masks Supported
164 //
165 #define CMLIB_HCELL_DEBUG 0x01
166
167 #ifndef ROUND_UP
168 #define ROUND_UP(a,b) ((((a)+(b)-1)/(b))*(b))
169 #define ROUND_DOWN(a,b) (((a)/(b))*(b))
170 #endif
171
172 //
173 // PAGE_SIZE definition
174 //
175 #ifndef PAGE_SIZE
176 #if defined(TARGET_i386) || defined(TARGET_amd64) || defined(TARGET_arm)
177 #define PAGE_SIZE 0x1000
178 #else
179 #error Local PAGE_SIZE definition required when built as host
180 #endif
181 #endif
182
183 #define TAG_CM ' MC'
184 #define TAG_KCB 'bkMC'
185 #define TAG_CMHIVE 'vHMC'
186 #define TAG_CMSD 'DSMC'
187
188 #define CMAPI NTAPI
189
190 #include <wine/unicode.h>
191 #include <wchar.h>
192 #include "hivedata.h"
193 #include "cmdata.h"
194
195 #if defined(_TYPEDEFS_HOST_H) || defined(__FREELDR_H) // || defined(_BLDR_)
196
197 #define PCM_KEY_SECURITY_CACHE_ENTRY PVOID
198 #define PCM_KEY_CONTROL_BLOCK PVOID
199 #define PCM_CELL_REMAP_BLOCK PVOID
200
201 // See also ntoskrnl/include/internal/cm.h
202 #define CMP_SECURITY_HASH_LISTS 64
203
204 // #endif // Commented out until one finds a way to properly include
205 // this header in freeldr and in ntoskrnl.
206
207 //
208 // Use Count Log and Entry
209 //
210 typedef struct _CM_USE_COUNT_LOG_ENTRY
211 {
212 HCELL_INDEX Cell;
213 PVOID Stack[7];
214 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY;
215
216 typedef struct _CM_USE_COUNT_LOG
217 {
218 USHORT Next;
219 USHORT Size;
220 CM_USE_COUNT_LOG_ENTRY Log[32];
221 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG;
222
223 //
224 // Configuration Manager Hive Structure
225 //
226 typedef struct _CMHIVE
227 {
228 HHIVE Hive;
229 HANDLE FileHandles[HFILE_TYPE_MAX];
230 LIST_ENTRY NotifyList;
231 LIST_ENTRY HiveList;
232 EX_PUSH_LOCK HiveLock;
233 PKTHREAD HiveLockOwner;
234 PKGUARDED_MUTEX ViewLock;
235 PKTHREAD ViewLockOwner;
236 EX_PUSH_LOCK WriterLock;
237 PKTHREAD WriterLockOwner;
238 PERESOURCE FlusherLock;
239 EX_PUSH_LOCK SecurityLock;
240 PKTHREAD HiveSecurityLockOwner;
241 LIST_ENTRY LRUViewListHead;
242 LIST_ENTRY PinViewListHead;
243 PFILE_OBJECT FileObject;
244 UNICODE_STRING FileFullPath;
245 UNICODE_STRING FileUserName;
246 USHORT MappedViews;
247 USHORT PinnedViews;
248 ULONG UseCount;
249 ULONG SecurityCount;
250 ULONG SecurityCacheSize;
251 LONG SecurityHitHint;
252 PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache;
253 LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS];
254 PKEVENT UnloadEvent;
255 PCM_KEY_CONTROL_BLOCK RootKcb;
256 BOOLEAN Frozen;
257 PWORK_QUEUE_ITEM UnloadWorkItem;
258 BOOLEAN GrowOnlyMode;
259 ULONG GrowOffset;
260 LIST_ENTRY KcbConvertListHead;
261 LIST_ENTRY KnodeConvertListHead;
262 PCM_CELL_REMAP_BLOCK CellRemapArray;
263 CM_USE_COUNT_LOG UseCountLog;
264 CM_USE_COUNT_LOG LockHiveLog;
265 ULONG Flags;
266 LIST_ENTRY TrustClassEntry;
267 ULONG FlushCount;
268 BOOLEAN HiveIsLoading;
269 PKTHREAD CreatorOwner;
270 } CMHIVE, *PCMHIVE;
271
272 #endif // See comment above
273
274 typedef struct _HV_HIVE_CELL_PAIR
275 {
276 PHHIVE Hive;
277 HCELL_INDEX Cell;
278 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR;
279
280 #define STATIC_CELL_PAIR_COUNT 4
281 typedef struct _HV_TRACK_CELL_REF
282 {
283 USHORT Count;
284 USHORT Max;
285 PHV_HIVE_CELL_PAIR CellArray;
286 HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT];
287 USHORT StaticCount;
288 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF;
289
290 extern ULONG CmlibTraceLevel;
291
292 //
293 // Hack since bigkeys are not yet supported
294 //
295 #define ASSERT_VALUE_BIG(h, s) \
296 ASSERTMSG("Big keys not supported!", !CmpIsKeyValueBig(h, s));
297
298 //
299 // Returns whether or not this is a small valued key
300 //
301 static inline
302 BOOLEAN
303 CmpIsKeyValueSmall(OUT PULONG RealLength,
304 IN ULONG Length)
305 {
306 /* Check if the length has the special size value */
307 if (Length >= CM_KEY_VALUE_SPECIAL_SIZE)
308 {
309 /* It does, so this is a small key: return the real length */
310 *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE;
311 return TRUE;
312 }
313
314 /* This is not a small key, return the length we read */
315 *RealLength = Length;
316 return FALSE;
317 }
318
319 //
320 // Returns whether or not this is a big valued key
321 //
322 static inline
323 BOOLEAN
324 CmpIsKeyValueBig(IN PHHIVE Hive,
325 IN ULONG Length)
326 {
327 /* Check if the hive is XP Beta 1 or newer */
328 if (Hive->Version >= HSYS_WHISTLER_BETA1)
329 {
330 /* Check if the key length is valid for a big value key */
331 if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG))
332 {
333 /* Yes, this value is big */
334 return TRUE;
335 }
336 }
337
338 /* Not a big value key */
339 return FALSE;
340 }
341
342 /*
343 * Public Hive functions.
344 */
345 NTSTATUS CMAPI
346 HvInitialize(
347 PHHIVE RegistryHive,
348 ULONG OperationType,
349 ULONG HiveFlags,
350 ULONG FileType,
351 PVOID HiveData OPTIONAL,
352 PALLOCATE_ROUTINE Allocate,
353 PFREE_ROUTINE Free,
354 PFILE_SET_SIZE_ROUTINE FileSetSize,
355 PFILE_WRITE_ROUTINE FileWrite,
356 PFILE_READ_ROUTINE FileRead,
357 PFILE_FLUSH_ROUTINE FileFlush,
358 ULONG Cluster OPTIONAL,
359 PCUNICODE_STRING FileName OPTIONAL);
360
361 VOID CMAPI
362 HvFree(
363 PHHIVE RegistryHive);
364
365 PVOID CMAPI
366 HvGetCell(
367 PHHIVE RegistryHive,
368 HCELL_INDEX CellOffset);
369
370 #define HvReleaseCell(h, c) \
371 do { \
372 if ((h)->ReleaseCellRoutine) \
373 (h)->ReleaseCellRoutine(h, c); \
374 } while(0)
375
376 LONG CMAPI
377 HvGetCellSize(
378 PHHIVE RegistryHive,
379 PVOID Cell);
380
381 HCELL_INDEX CMAPI
382 HvAllocateCell(
383 PHHIVE RegistryHive,
384 ULONG Size,
385 HSTORAGE_TYPE Storage,
386 IN HCELL_INDEX Vicinity);
387
388 BOOLEAN CMAPI
389 HvIsCellAllocated(
390 IN PHHIVE RegistryHive,
391 IN HCELL_INDEX CellIndex
392 );
393
394 HCELL_INDEX CMAPI
395 HvReallocateCell(
396 PHHIVE RegistryHive,
397 HCELL_INDEX CellOffset,
398 ULONG Size);
399
400 VOID CMAPI
401 HvFreeCell(
402 PHHIVE RegistryHive,
403 HCELL_INDEX CellOffset);
404
405 BOOLEAN CMAPI
406 HvMarkCellDirty(
407 PHHIVE RegistryHive,
408 HCELL_INDEX CellOffset,
409 BOOLEAN HoldingLock);
410
411 BOOLEAN CMAPI
412 HvIsCellDirty(
413 IN PHHIVE Hive,
414 IN HCELL_INDEX Cell
415 );
416
417 BOOLEAN
418 CMAPI
419 HvHiveWillShrink(
420 IN PHHIVE RegistryHive
421 );
422
423 BOOLEAN CMAPI
424 HvSyncHive(
425 PHHIVE RegistryHive);
426
427 BOOLEAN CMAPI
428 HvWriteHive(
429 PHHIVE RegistryHive);
430
431 BOOLEAN
432 CMAPI
433 HvTrackCellRef(
434 PHV_TRACK_CELL_REF CellRef,
435 PHHIVE Hive,
436 HCELL_INDEX Cell
437 );
438
439 VOID
440 CMAPI
441 HvReleaseFreeCellRefArray(
442 PHV_TRACK_CELL_REF CellRef
443 );
444
445 /*
446 * Private functions.
447 */
448
449 PHBIN CMAPI
450 HvpAddBin(
451 PHHIVE RegistryHive,
452 ULONG Size,
453 HSTORAGE_TYPE Storage);
454
455 NTSTATUS CMAPI
456 HvpCreateHiveFreeCellList(
457 PHHIVE Hive);
458
459 ULONG CMAPI
460 HvpHiveHeaderChecksum(
461 PHBASE_BLOCK HiveHeader);
462
463
464 /* Old-style Public "Cmlib" functions */
465
466 BOOLEAN CMAPI
467 CmCreateRootNode(
468 PHHIVE Hive,
469 PCWSTR Name);
470
471 VOID CMAPI
472 CmPrepareHive(
473 PHHIVE RegistryHive);
474
475
476 /* NT-style Public Cm functions */
477
478 //
479 // Cell Index Routines
480 //
481 HCELL_INDEX
482 NTAPI
483 CmpFindSubKeyByName(
484 IN PHHIVE Hive,
485 IN PCM_KEY_NODE Parent,
486 IN PCUNICODE_STRING SearchName
487 );
488
489 HCELL_INDEX
490 NTAPI
491 CmpFindSubKeyByNumber(
492 IN PHHIVE Hive,
493 IN PCM_KEY_NODE Node,
494 IN ULONG Number
495 );
496
497 ULONG
498 NTAPI
499 CmpComputeHashKey(
500 IN ULONG Hash,
501 IN PCUNICODE_STRING Name,
502 IN BOOLEAN AllowSeparators
503 );
504
505 BOOLEAN
506 NTAPI
507 CmpAddSubKey(
508 IN PHHIVE Hive,
509 IN HCELL_INDEX Parent,
510 IN HCELL_INDEX Child
511 );
512
513 BOOLEAN
514 NTAPI
515 CmpRemoveSubKey(
516 IN PHHIVE Hive,
517 IN HCELL_INDEX ParentKey,
518 IN HCELL_INDEX TargetKey
519 );
520
521 BOOLEAN
522 NTAPI
523 CmpMarkIndexDirty(
524 IN PHHIVE Hive,
525 HCELL_INDEX ParentKey,
526 HCELL_INDEX TargetKey
527 );
528
529
530 //
531 // Name Functions
532 //
533 LONG
534 NTAPI
535 CmpCompareCompressedName(
536 IN PCUNICODE_STRING SearchName,
537 IN PWCHAR CompressedName,
538 IN ULONG NameLength
539 );
540
541 USHORT
542 NTAPI
543 CmpNameSize(
544 IN PHHIVE Hive,
545 IN PUNICODE_STRING Name
546 );
547
548 USHORT
549 NTAPI
550 CmpCompressedNameSize(
551 IN PWCHAR Name,
552 IN ULONG Length
553 );
554
555 USHORT
556 NTAPI
557 CmpCopyName(
558 IN PHHIVE Hive,
559 IN PWCHAR Destination,
560 IN PUNICODE_STRING Source
561 );
562
563 VOID
564 NTAPI
565 CmpCopyCompressedName(
566 IN PWCHAR Destination,
567 IN ULONG DestinationLength,
568 IN PWCHAR Source,
569 IN ULONG SourceLength
570 );
571
572 BOOLEAN
573 NTAPI
574 CmpFindNameInList(
575 IN PHHIVE Hive,
576 IN PCHILD_LIST ChildList,
577 IN PUNICODE_STRING Name,
578 OUT PULONG ChildIndex,
579 OUT PHCELL_INDEX CellIndex
580 );
581
582
583 //
584 // Cell Value Routines
585 //
586 HCELL_INDEX
587 NTAPI
588 CmpFindValueByName(
589 IN PHHIVE Hive,
590 IN PCM_KEY_NODE KeyNode,
591 IN PUNICODE_STRING Name
592 );
593
594 PCELL_DATA
595 NTAPI
596 CmpValueToData(
597 IN PHHIVE Hive,
598 IN PCM_KEY_VALUE Value,
599 OUT PULONG Length
600 );
601
602 NTSTATUS
603 NTAPI
604 CmpSetValueDataNew(
605 IN PHHIVE Hive,
606 IN PVOID Data,
607 IN ULONG DataSize,
608 IN ULONG StorageType,
609 IN HCELL_INDEX ValueCell,
610 OUT PHCELL_INDEX DataCell
611 );
612
613 NTSTATUS
614 NTAPI
615 CmpAddValueToList(
616 IN PHHIVE Hive,
617 IN HCELL_INDEX ValueCell,
618 IN ULONG Index,
619 IN ULONG Type,
620 IN OUT PCHILD_LIST ChildList
621 );
622
623 BOOLEAN
624 NTAPI
625 CmpFreeValue(
626 IN PHHIVE Hive,
627 IN HCELL_INDEX Cell
628 );
629
630 BOOLEAN
631 NTAPI
632 CmpMarkValueDataDirty(
633 IN PHHIVE Hive,
634 IN PCM_KEY_VALUE Value
635 );
636
637 BOOLEAN
638 NTAPI
639 CmpFreeValueData(
640 IN PHHIVE Hive,
641 IN HCELL_INDEX DataCell,
642 IN ULONG DataLength
643 );
644
645 NTSTATUS
646 NTAPI
647 CmpRemoveValueFromList(
648 IN PHHIVE Hive,
649 IN ULONG Index,
650 IN OUT PCHILD_LIST ChildList
651 );
652
653 BOOLEAN
654 NTAPI
655 CmpGetValueData(
656 IN PHHIVE Hive,
657 IN PCM_KEY_VALUE Value,
658 OUT PULONG Length,
659 OUT PVOID *Buffer,
660 OUT PBOOLEAN BufferAllocated,
661 OUT PHCELL_INDEX CellToRelease
662 );
663
664 NTSTATUS
665 NTAPI
666 CmpCopyKeyValueList(
667 IN PHHIVE SourceHive,
668 IN PCHILD_LIST SrcValueList,
669 IN PHHIVE DestinationHive,
670 IN OUT PCHILD_LIST DestValueList,
671 IN HSTORAGE_TYPE StorageType
672 );
673
674 NTSTATUS
675 NTAPI
676 CmpFreeKeyByCell(
677 IN PHHIVE Hive,
678 IN HCELL_INDEX Cell,
679 IN BOOLEAN Unlink
680 );
681
682 VOID
683 NTAPI
684 CmpRemoveSecurityCellList(
685 IN PHHIVE Hive,
686 IN HCELL_INDEX SecurityCell
687 );
688
689 VOID
690 NTAPI
691 CmpFreeSecurityDescriptor(
692 IN PHHIVE Hive,
693 IN HCELL_INDEX Cell
694 );
695
696 /******************************************************************************/
697
698 /* To be implemented by the user of this library */
699 PVOID
700 NTAPI
701 CmpAllocate(
702 IN SIZE_T Size,
703 IN BOOLEAN Paged,
704 IN ULONG Tag
705 );
706
707 VOID
708 NTAPI
709 CmpFree(
710 IN PVOID Ptr,
711 IN ULONG Quota
712 );
713
714 #endif /* _CMLIB_H_ */