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