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(__FREELDR_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 freeldr 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 PVOID CMAPI 388 HvGetCell( 389 PHHIVE RegistryHive, 390 HCELL_INDEX CellOffset); 391 392 #define HvReleaseCell(h, c) \ 393 do { \ 394 if ((h)->ReleaseCellRoutine) \ 395 (h)->ReleaseCellRoutine(h, c); \ 396 } while(0) 397 398 LONG CMAPI 399 HvGetCellSize( 400 PHHIVE RegistryHive, 401 PVOID Cell); 402 403 HCELL_INDEX CMAPI 404 HvAllocateCell( 405 PHHIVE RegistryHive, 406 ULONG Size, 407 HSTORAGE_TYPE Storage, 408 IN HCELL_INDEX Vicinity); 409 410 BOOLEAN CMAPI 411 HvIsCellAllocated( 412 IN PHHIVE RegistryHive, 413 IN HCELL_INDEX CellIndex 414 ); 415 416 HCELL_INDEX CMAPI 417 HvReallocateCell( 418 PHHIVE RegistryHive, 419 HCELL_INDEX CellOffset, 420 ULONG Size); 421 422 VOID CMAPI 423 HvFreeCell( 424 PHHIVE RegistryHive, 425 HCELL_INDEX CellOffset); 426 427 BOOLEAN CMAPI 428 HvMarkCellDirty( 429 PHHIVE RegistryHive, 430 HCELL_INDEX CellOffset, 431 BOOLEAN HoldingLock); 432 433 BOOLEAN CMAPI 434 HvIsCellDirty( 435 IN PHHIVE Hive, 436 IN HCELL_INDEX Cell 437 ); 438 439 BOOLEAN 440 CMAPI 441 HvHiveWillShrink( 442 IN PHHIVE RegistryHive 443 ); 444 445 BOOLEAN CMAPI 446 HvSyncHive( 447 PHHIVE RegistryHive); 448 449 BOOLEAN CMAPI 450 HvWriteHive( 451 PHHIVE RegistryHive); 452 453 BOOLEAN 454 CMAPI 455 HvTrackCellRef( 456 IN OUT PHV_TRACK_CELL_REF CellRef, 457 IN PHHIVE Hive, 458 IN HCELL_INDEX Cell 459 ); 460 461 VOID 462 CMAPI 463 HvReleaseFreeCellRefArray( 464 IN OUT PHV_TRACK_CELL_REF CellRef 465 ); 466 467 /* 468 * Private functions. 469 */ 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 PUNICODE_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 PUNICODE_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 PUNICODE_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 PUNICODE_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