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) ((void)(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 156 #else 157 158 // 159 // Debug/Tracing support 160 // 161 #if _CMLIB_DEBUG_ 162 #ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented 163 #define CMLTRACE DbgPrintEx 164 #else 165 #define CMLTRACE(x, ...) \ 166 if (x & CmlibTraceLevel) DbgPrint(__VA_ARGS__) 167 #endif 168 #else 169 #define CMLTRACE(x, ...) DPRINT(__VA_ARGS__) 170 #endif 171 172 #include <ntdef.h> 173 #include <ntifs.h> 174 #include <bugcodes.h> 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 /* Forward declarations */ 218 typedef struct _CM_KEY_SECURITY_CACHE_ENTRY *PCM_KEY_SECURITY_CACHE_ENTRY; 219 typedef struct _CM_KEY_CONTROL_BLOCK *PCM_KEY_CONTROL_BLOCK; 220 typedef struct _CM_CELL_REMAP_BLOCK *PCM_CELL_REMAP_BLOCK; 221 222 // See ntoskrnl/include/internal/cm.h 223 #define CMP_SECURITY_HASH_LISTS 64 224 225 // 226 // Use Count Log and Entry 227 // 228 typedef struct _CM_USE_COUNT_LOG_ENTRY 229 { 230 HCELL_INDEX Cell; 231 PVOID Stack[7]; 232 } CM_USE_COUNT_LOG_ENTRY, *PCM_USE_COUNT_LOG_ENTRY; 233 234 typedef struct _CM_USE_COUNT_LOG 235 { 236 USHORT Next; 237 USHORT Size; 238 CM_USE_COUNT_LOG_ENTRY Log[32]; 239 } CM_USE_COUNT_LOG, *PCM_USE_COUNT_LOG; 240 241 // 242 // Configuration Manager Hive Structure 243 // 244 typedef struct _CMHIVE 245 { 246 HHIVE Hive; 247 HANDLE FileHandles[HFILE_TYPE_MAX]; 248 LIST_ENTRY NotifyList; 249 LIST_ENTRY HiveList; 250 EX_PUSH_LOCK HiveLock; 251 PKTHREAD HiveLockOwner; 252 PKGUARDED_MUTEX ViewLock; 253 PKTHREAD ViewLockOwner; 254 EX_PUSH_LOCK WriterLock; 255 PKTHREAD WriterLockOwner; 256 PERESOURCE FlusherLock; 257 EX_PUSH_LOCK SecurityLock; 258 PKTHREAD HiveSecurityLockOwner; 259 LIST_ENTRY LRUViewListHead; 260 LIST_ENTRY PinViewListHead; 261 PFILE_OBJECT FileObject; 262 UNICODE_STRING FileFullPath; 263 UNICODE_STRING FileUserName; 264 USHORT MappedViews; 265 USHORT PinnedViews; 266 ULONG UseCount; 267 ULONG SecurityCount; 268 ULONG SecurityCacheSize; 269 LONG SecurityHitHint; 270 PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache; 271 LIST_ENTRY SecurityHash[CMP_SECURITY_HASH_LISTS]; 272 PKEVENT UnloadEvent; 273 PCM_KEY_CONTROL_BLOCK RootKcb; 274 BOOLEAN Frozen; 275 PWORK_QUEUE_ITEM UnloadWorkItem; 276 BOOLEAN GrowOnlyMode; 277 ULONG GrowOffset; 278 LIST_ENTRY KcbConvertListHead; 279 LIST_ENTRY KnodeConvertListHead; 280 PCM_CELL_REMAP_BLOCK CellRemapArray; 281 CM_USE_COUNT_LOG UseCountLog; 282 CM_USE_COUNT_LOG LockHiveLog; 283 ULONG Flags; 284 LIST_ENTRY TrustClassEntry; 285 ULONG FlushCount; 286 BOOLEAN HiveIsLoading; 287 PKTHREAD CreatorOwner; 288 } CMHIVE, *PCMHIVE; 289 290 typedef struct _HV_HIVE_CELL_PAIR 291 { 292 PHHIVE Hive; 293 HCELL_INDEX Cell; 294 } HV_HIVE_CELL_PAIR, *PHV_HIVE_CELL_PAIR; 295 296 #define STATIC_CELL_PAIR_COUNT 4 297 typedef struct _HV_TRACK_CELL_REF 298 { 299 USHORT Count; 300 USHORT Max; 301 PHV_HIVE_CELL_PAIR CellArray; 302 HV_HIVE_CELL_PAIR StaticArray[STATIC_CELL_PAIR_COUNT]; 303 USHORT StaticCount; 304 } HV_TRACK_CELL_REF, *PHV_TRACK_CELL_REF; 305 306 extern ULONG CmlibTraceLevel; 307 308 // 309 // Hack since big keys are not yet supported 310 // 311 #define ASSERT_VALUE_BIG(h, s) \ 312 ASSERTMSG("Big keys not supported!\n", !CmpIsKeyValueBig(h, s)); 313 314 // 315 // Returns whether or not this is a small valued key 316 // 317 static inline 318 BOOLEAN 319 CmpIsKeyValueSmall(OUT PULONG RealLength, 320 IN ULONG Length) 321 { 322 /* Check if the length has the special size value */ 323 if (Length >= CM_KEY_VALUE_SPECIAL_SIZE) 324 { 325 /* It does, so this is a small key: return the real length */ 326 *RealLength = Length - CM_KEY_VALUE_SPECIAL_SIZE; 327 return TRUE; 328 } 329 330 /* This is not a small key, return the length we read */ 331 *RealLength = Length; 332 return FALSE; 333 } 334 335 // 336 // Returns whether or not this is a big valued key 337 // 338 static inline 339 BOOLEAN 340 CmpIsKeyValueBig(IN PHHIVE Hive, 341 IN ULONG Length) 342 { 343 /* Check if the hive is XP Beta 1 or newer */ 344 if (Hive->Version >= HSYS_WHISTLER_BETA1) 345 { 346 /* Check if the key length is valid for a big value key */ 347 if ((Length < CM_KEY_VALUE_SPECIAL_SIZE) && (Length > CM_KEY_VALUE_BIG)) 348 { 349 /* Yes, this value is big */ 350 return TRUE; 351 } 352 } 353 354 /* Not a big value key */ 355 return FALSE; 356 } 357 358 /* 359 * Public Hive functions. 360 */ 361 NTSTATUS CMAPI 362 HvInitialize( 363 PHHIVE RegistryHive, 364 ULONG OperationType, 365 ULONG HiveFlags, 366 ULONG FileType, 367 PVOID HiveData OPTIONAL, 368 PALLOCATE_ROUTINE Allocate, 369 PFREE_ROUTINE Free, 370 PFILE_SET_SIZE_ROUTINE FileSetSize, 371 PFILE_WRITE_ROUTINE FileWrite, 372 PFILE_READ_ROUTINE FileRead, 373 PFILE_FLUSH_ROUTINE FileFlush, 374 ULONG Cluster OPTIONAL, 375 PCUNICODE_STRING FileName OPTIONAL); 376 377 VOID CMAPI 378 HvFree( 379 PHHIVE RegistryHive); 380 381 #define HvGetCell(Hive, Cell) \ 382 (Hive)->GetCellRoutine(Hive, Cell) 383 384 #define HvReleaseCell(Hive, Cell) \ 385 do { \ 386 if ((Hive)->ReleaseCellRoutine) \ 387 (Hive)->ReleaseCellRoutine(Hive, Cell); \ 388 } while(0) 389 390 LONG CMAPI 391 HvGetCellSize( 392 PHHIVE RegistryHive, 393 PVOID Cell); 394 395 HCELL_INDEX CMAPI 396 HvAllocateCell( 397 PHHIVE RegistryHive, 398 ULONG Size, 399 HSTORAGE_TYPE Storage, 400 IN HCELL_INDEX Vicinity); 401 402 BOOLEAN CMAPI 403 HvIsCellAllocated( 404 IN PHHIVE RegistryHive, 405 IN HCELL_INDEX CellIndex 406 ); 407 408 HCELL_INDEX CMAPI 409 HvReallocateCell( 410 PHHIVE RegistryHive, 411 HCELL_INDEX CellOffset, 412 ULONG Size); 413 414 VOID CMAPI 415 HvFreeCell( 416 PHHIVE RegistryHive, 417 HCELL_INDEX CellOffset); 418 419 BOOLEAN CMAPI 420 HvMarkCellDirty( 421 PHHIVE RegistryHive, 422 HCELL_INDEX CellOffset, 423 BOOLEAN HoldingLock); 424 425 BOOLEAN CMAPI 426 HvIsCellDirty( 427 IN PHHIVE Hive, 428 IN HCELL_INDEX Cell 429 ); 430 431 BOOLEAN 432 CMAPI 433 HvHiveWillShrink( 434 IN PHHIVE RegistryHive 435 ); 436 437 BOOLEAN CMAPI 438 HvSyncHive( 439 PHHIVE RegistryHive); 440 441 BOOLEAN CMAPI 442 HvWriteHive( 443 PHHIVE RegistryHive); 444 445 BOOLEAN 446 CMAPI 447 HvTrackCellRef( 448 IN OUT PHV_TRACK_CELL_REF CellRef, 449 IN PHHIVE Hive, 450 IN HCELL_INDEX Cell 451 ); 452 453 VOID 454 CMAPI 455 HvReleaseFreeCellRefArray( 456 IN OUT PHV_TRACK_CELL_REF CellRef 457 ); 458 459 /* 460 * Private functions. 461 */ 462 463 PCELL_DATA CMAPI 464 HvpGetCellData( 465 _In_ PHHIVE Hive, 466 _In_ HCELL_INDEX CellIndex); 467 468 PHBIN CMAPI 469 HvpAddBin( 470 PHHIVE RegistryHive, 471 ULONG Size, 472 HSTORAGE_TYPE Storage); 473 474 NTSTATUS CMAPI 475 HvpCreateHiveFreeCellList( 476 PHHIVE Hive); 477 478 ULONG CMAPI 479 HvpHiveHeaderChecksum( 480 PHBASE_BLOCK HiveHeader); 481 482 483 /* Old-style Public "Cmlib" functions */ 484 485 BOOLEAN CMAPI 486 CmCreateRootNode( 487 PHHIVE Hive, 488 PCWSTR Name); 489 490 VOID CMAPI 491 CmPrepareHive( 492 PHHIVE RegistryHive); 493 494 495 /* NT-style Public Cm functions */ 496 497 // 498 // Cell Index Routines 499 // 500 HCELL_INDEX 501 NTAPI 502 CmpFindSubKeyByName( 503 IN PHHIVE Hive, 504 IN PCM_KEY_NODE Parent, 505 IN PCUNICODE_STRING SearchName 506 ); 507 508 HCELL_INDEX 509 NTAPI 510 CmpFindSubKeyByNumber( 511 IN PHHIVE Hive, 512 IN PCM_KEY_NODE Node, 513 IN ULONG Number 514 ); 515 516 ULONG 517 NTAPI 518 CmpComputeHashKey( 519 IN ULONG Hash, 520 IN PCUNICODE_STRING Name, 521 IN BOOLEAN AllowSeparators 522 ); 523 524 BOOLEAN 525 NTAPI 526 CmpAddSubKey( 527 IN PHHIVE Hive, 528 IN HCELL_INDEX Parent, 529 IN HCELL_INDEX Child 530 ); 531 532 BOOLEAN 533 NTAPI 534 CmpRemoveSubKey( 535 IN PHHIVE Hive, 536 IN HCELL_INDEX ParentKey, 537 IN HCELL_INDEX TargetKey 538 ); 539 540 BOOLEAN 541 NTAPI 542 CmpMarkIndexDirty( 543 IN PHHIVE Hive, 544 HCELL_INDEX ParentKey, 545 HCELL_INDEX TargetKey 546 ); 547 548 549 // 550 // Name Functions 551 // 552 LONG 553 NTAPI 554 CmpCompareCompressedName( 555 IN PCUNICODE_STRING SearchName, 556 IN PWCHAR CompressedName, 557 IN ULONG NameLength 558 ); 559 560 USHORT 561 NTAPI 562 CmpNameSize( 563 IN PHHIVE Hive, 564 IN PCUNICODE_STRING Name 565 ); 566 567 USHORT 568 NTAPI 569 CmpCompressedNameSize( 570 IN PWCHAR Name, 571 IN ULONG Length 572 ); 573 574 USHORT 575 NTAPI 576 CmpCopyName( 577 IN PHHIVE Hive, 578 OUT PWCHAR Destination, 579 IN PCUNICODE_STRING Source 580 ); 581 582 VOID 583 NTAPI 584 CmpCopyCompressedName( 585 OUT PWCHAR Destination, 586 IN ULONG DestinationLength, 587 IN PWCHAR Source, 588 IN ULONG SourceLength 589 ); 590 591 BOOLEAN 592 NTAPI 593 CmpFindNameInList( 594 IN PHHIVE Hive, 595 IN PCHILD_LIST ChildList, 596 IN PCUNICODE_STRING Name, 597 OUT PULONG ChildIndex OPTIONAL, 598 OUT PHCELL_INDEX CellIndex 599 ); 600 601 602 // 603 // Cell Value Routines 604 // 605 HCELL_INDEX 606 NTAPI 607 CmpFindValueByName( 608 IN PHHIVE Hive, 609 IN PCM_KEY_NODE KeyNode, 610 IN PCUNICODE_STRING Name 611 ); 612 613 PCELL_DATA 614 NTAPI 615 CmpValueToData( 616 IN PHHIVE Hive, 617 IN PCM_KEY_VALUE Value, 618 OUT PULONG Length 619 ); 620 621 NTSTATUS 622 NTAPI 623 CmpSetValueDataNew( 624 IN PHHIVE Hive, 625 IN PVOID Data, 626 IN ULONG DataSize, 627 IN HSTORAGE_TYPE StorageType, 628 IN HCELL_INDEX ValueCell, 629 OUT PHCELL_INDEX DataCell 630 ); 631 632 NTSTATUS 633 NTAPI 634 CmpAddValueToList( 635 IN PHHIVE Hive, 636 IN HCELL_INDEX ValueCell, 637 IN ULONG Index, 638 IN HSTORAGE_TYPE StorageType, 639 IN OUT PCHILD_LIST ChildList 640 ); 641 642 BOOLEAN 643 NTAPI 644 CmpFreeValue( 645 IN PHHIVE Hive, 646 IN HCELL_INDEX Cell 647 ); 648 649 BOOLEAN 650 NTAPI 651 CmpMarkValueDataDirty( 652 IN PHHIVE Hive, 653 IN PCM_KEY_VALUE Value 654 ); 655 656 BOOLEAN 657 NTAPI 658 CmpFreeValueData( 659 IN PHHIVE Hive, 660 IN HCELL_INDEX DataCell, 661 IN ULONG DataLength 662 ); 663 664 NTSTATUS 665 NTAPI 666 CmpRemoveValueFromList( 667 IN PHHIVE Hive, 668 IN ULONG Index, 669 IN OUT PCHILD_LIST ChildList 670 ); 671 672 BOOLEAN 673 NTAPI 674 CmpGetValueData( 675 IN PHHIVE Hive, 676 IN PCM_KEY_VALUE Value, 677 OUT PULONG Length, 678 OUT PVOID *Buffer, 679 OUT PBOOLEAN BufferAllocated, 680 OUT PHCELL_INDEX CellToRelease 681 ); 682 683 NTSTATUS 684 NTAPI 685 CmpCopyKeyValueList( 686 IN PHHIVE SourceHive, 687 IN PCHILD_LIST SrcValueList, 688 IN PHHIVE DestinationHive, 689 IN OUT PCHILD_LIST DestValueList, 690 IN HSTORAGE_TYPE StorageType 691 ); 692 693 NTSTATUS 694 NTAPI 695 CmpFreeKeyByCell( 696 IN PHHIVE Hive, 697 IN HCELL_INDEX Cell, 698 IN BOOLEAN Unlink 699 ); 700 701 VOID 702 NTAPI 703 CmpRemoveSecurityCellList( 704 IN PHHIVE Hive, 705 IN HCELL_INDEX SecurityCell 706 ); 707 708 VOID 709 NTAPI 710 CmpFreeSecurityDescriptor( 711 IN PHHIVE Hive, 712 IN HCELL_INDEX Cell 713 ); 714 715 /******************************************************************************/ 716 717 /* To be implemented by the user of this library */ 718 PVOID 719 NTAPI 720 CmpAllocate( 721 IN SIZE_T Size, 722 IN BOOLEAN Paged, 723 IN ULONG Tag 724 ); 725 726 VOID 727 NTAPI 728 CmpFree( 729 IN PVOID Ptr, 730 IN ULONG Quota 731 ); 732 733 #endif /* _CMLIB_H_ */ 734