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