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