1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 ModuleName: 6 7 MxGeneralKm.h 8 9 Abstract: 10 11 Kernel mode implementation for general OS 12 functions defined in MxGeneral.h 13 14 Author: 15 16 17 18 Revision History: 19 20 21 22 --*/ 23 24 #pragma once 25 26 #define MAKE_MX_FUNC_NAME(x) L##x 27 typedef LPCWSTR MxFuncName; 28 typedef PKTHREAD MxThread; 29 typedef PETHREAD MdEThread; 30 typedef PDEVICE_OBJECT MdDeviceObject; 31 typedef PDRIVER_OBJECT MdDriverObject; 32 typedef PFILE_OBJECT MdFileObject; 33 typedef PIO_REMOVE_LOCK MdRemoveLock; 34 typedef PCALLBACK_OBJECT MdCallbackObject; 35 typedef CALLBACK_FUNCTION MdCallbackFunctionType, *MdCallbackFunction; 36 typedef PKINTERRUPT MdInterrupt; 37 typedef KSERVICE_ROUTINE MdInterruptServiceRoutineType, *MdInterruptServiceRoutine; 38 typedef KSYNCHRONIZE_ROUTINE MdInterruptSynchronizeRoutineType, *MdInterruptSynchronizeRoutine; 39 40 #include "mxgeneral.h" 41 #include <ntstrsafe.h> 42 43 __inline 44 BOOLEAN 45 Mx::IsUM( 46 ) 47 { 48 return FALSE; 49 } 50 51 __inline 52 BOOLEAN 53 Mx::IsKM( 54 ) 55 { 56 return TRUE; 57 } 58 59 __inline 60 MxThread 61 Mx::MxGetCurrentThread( 62 ) 63 { 64 return KeGetCurrentThread(); 65 } 66 67 __inline 68 MdEThread 69 Mx::GetCurrentEThread( 70 ) 71 { 72 return PsGetCurrentThread(); 73 } 74 75 __inline 76 NTSTATUS 77 Mx::MxTerminateCurrentThread( 78 __in NTSTATUS Status 79 ) 80 { 81 return PsTerminateSystemThread(Status); 82 } 83 84 __inline 85 KIRQL 86 Mx::MxGetCurrentIrql( 87 ) 88 { 89 return KeGetCurrentIrql(); 90 } 91 92 __drv_maxIRQL(HIGH_LEVEL) 93 __drv_raisesIRQL(NewIrql) 94 __inline 95 VOID 96 Mx::MxRaiseIrql( 97 __in KIRQL NewIrql, 98 __out __deref __drv_savesIRQL PKIRQL OldIrql 99 ) 100 { 101 KeRaiseIrql(NewIrql, OldIrql); 102 } 103 104 __drv_maxIRQL(HIGH_LEVEL) 105 __inline 106 VOID 107 Mx::MxLowerIrql( 108 __in __drv_restoresIRQL __drv_nonConstant KIRQL NewIrql 109 ) 110 { 111 KeLowerIrql(NewIrql); 112 } 113 114 __inline 115 VOID 116 Mx::MxQueryTickCount( 117 __out PLARGE_INTEGER TickCount 118 ) 119 { 120 KeQueryTickCount(TickCount); 121 } 122 123 __inline 124 ULONG 125 Mx::MxQueryTimeIncrement( 126 ) 127 { 128 return KeQueryTimeIncrement(); 129 } 130 131 __inline 132 VOID 133 Mx::MxBugCheckEx( 134 __in ULONG BugCheckCode, 135 __in ULONG_PTR BugCheckParameter1, 136 __in ULONG_PTR BugCheckParameter2, 137 __in ULONG_PTR BugCheckParameter3, 138 __in ULONG_PTR BugCheckParameter4 139 ) 140 { 141 #ifdef _MSC_VER 142 #pragma prefast(suppress:__WARNING_USE_OTHER_FUNCTION, "KeBugCheckEx is the intent."); 143 #endif 144 KeBugCheckEx( 145 BugCheckCode, 146 BugCheckParameter1, 147 BugCheckParameter2, 148 BugCheckParameter3, 149 BugCheckParameter4 150 ); 151 152 UNREACHABLE; 153 } 154 155 __inline 156 VOID 157 Mx::MxDbgBreakPoint( 158 ) 159 { 160 DbgBreakPoint(); 161 } 162 163 __inline 164 VOID 165 Mx::MxAssert( 166 __in BOOLEAN Condition 167 ) 168 { 169 UNREFERENCED_PARAMETER(Condition); 170 171 ASSERT(Condition); //this get defined as RtlAssert 172 } 173 174 __inline 175 VOID 176 Mx::MxAssertMsg( 177 __in LPSTR Message, 178 __in BOOLEAN Condition 179 ) 180 { 181 UNREFERENCED_PARAMETER(Message); 182 UNREFERENCED_PARAMETER(Condition); 183 184 ASSERT(Condition); 185 186 // ASSERTMSG(Message, Condition); TODO: wtf 187 } 188 189 _Acquires_lock_(_Global_critical_region_) 190 __inline 191 VOID 192 Mx::MxEnterCriticalRegion( 193 ) 194 { 195 KeEnterCriticalRegion(); 196 } 197 198 _Releases_lock_(_Global_critical_region_) 199 __inline 200 VOID 201 Mx::MxLeaveCriticalRegion( 202 ) 203 { 204 KeLeaveCriticalRegion(); 205 } 206 207 __inline 208 VOID 209 Mx::MxDelayExecutionThread( 210 __in KPROCESSOR_MODE WaitMode, 211 __in BOOLEAN Alertable, 212 __in PLARGE_INTEGER Interval 213 ) 214 { 215 ASSERTMSG("Interval must be relative\n", Interval->QuadPart <= 0); 216 217 KeDelayExecutionThread( 218 WaitMode, 219 Alertable, 220 Interval 221 ); 222 } 223 224 __inline 225 PVOID 226 Mx::MxGetSystemRoutineAddress( 227 __in MxFuncName FuncName 228 ) 229 { 230 UNICODE_STRING funcName; 231 232 RtlInitUnicodeString(&funcName, FuncName); 233 return MmGetSystemRoutineAddress(&funcName); 234 } 235 236 __inline 237 VOID 238 Mx::MxReferenceObject( 239 __in PVOID Object 240 ) 241 { 242 ObReferenceObject(Object); 243 } 244 245 __inline 246 VOID 247 Mx::MxDereferenceObject( 248 __in PVOID Object 249 ) 250 { 251 ObDereferenceObject(Object); 252 } 253 254 __inline 255 VOID 256 Mx::MxInitializeRemoveLock( 257 __in MdRemoveLock Lock, 258 __in ULONG AllocateTag, 259 __in ULONG MaxLockedMinutes, 260 __in ULONG HighWatermark 261 ) 262 { 263 IoInitializeRemoveLock(Lock, AllocateTag, MaxLockedMinutes, HighWatermark); 264 } 265 266 __inline 267 NTSTATUS 268 Mx::MxAcquireRemoveLock( 269 __in MdRemoveLock RemoveLock, 270 __in_opt PVOID Tag 271 ) 272 { 273 return IoAcquireRemoveLock(RemoveLock, Tag); 274 } 275 276 __inline 277 VOID 278 Mx::MxReleaseRemoveLock( 279 __in MdRemoveLock RemoveLock, 280 __in PVOID Tag 281 ) 282 { 283 IoReleaseRemoveLock(RemoveLock, Tag); 284 } 285 286 __inline 287 VOID 288 Mx::MxReleaseRemoveLockAndWait( 289 __in MdRemoveLock RemoveLock, 290 __in PVOID Tag 291 ) 292 { 293 IoReleaseRemoveLockAndWait(RemoveLock, Tag); 294 } 295 296 __inline 297 BOOLEAN 298 Mx::MxHasEnoughRemainingThreadStack( 299 VOID 300 ) 301 { 302 return (IoGetRemainingStackSize() < KERNEL_STACK_SIZE/2) ? FALSE : TRUE; 303 } 304 305 _Releases_lock_(_Global_cancel_spin_lock_) 306 __drv_requiresIRQL(DISPATCH_LEVEL) 307 __inline 308 VOID 309 Mx::ReleaseCancelSpinLock( 310 __in __drv_restoresIRQL __drv_useCancelIRQL KIRQL Irql 311 ) 312 { 313 IoReleaseCancelSpinLock(Irql); 314 } 315 316 __inline 317 NTSTATUS 318 Mx::CreateCallback( 319 __out PCALLBACK_OBJECT *CallbackObject, 320 __in POBJECT_ATTRIBUTES ObjectAttributes, 321 __in BOOLEAN Create, 322 __in BOOLEAN AllowMultipleCallbacks 323 ) 324 { 325 return ExCreateCallback( 326 CallbackObject, 327 ObjectAttributes, 328 Create, 329 AllowMultipleCallbacks); 330 } 331 332 __inline 333 PVOID 334 Mx::RegisterCallback( 335 __in PCALLBACK_OBJECT CallbackObject, 336 __in MdCallbackFunction CallbackFunction, 337 __in PVOID CallbackContext 338 ) 339 { 340 return ExRegisterCallback( 341 CallbackObject, 342 CallbackFunction, 343 CallbackContext); 344 } 345 346 __inline 347 VOID 348 Mx::UnregisterCallback( 349 __in PVOID CbRegistration 350 ) 351 { 352 ExUnregisterCallback(CbRegistration); 353 } 354 355 __inline 356 VOID 357 Mx::MxUnlockPages( 358 __in PMDL Mdl 359 ) 360 { 361 MmUnlockPages(Mdl); 362 } 363 364 __inline 365 PVOID 366 Mx::MxGetSystemAddressForMdlSafe( 367 __inout PMDL Mdl, 368 __in ULONG Priority 369 ) 370 { 371 return MmGetSystemAddressForMdlSafe(Mdl, Priority); 372 } 373 374 __inline 375 VOID 376 Mx::MxBuildMdlForNonPagedPool( 377 __inout PMDL Mdl 378 ) 379 { 380 MmBuildMdlForNonPagedPool(Mdl); 381 } 382 383 __inline 384 PVOID 385 Mx::MxGetDriverObjectExtension( 386 __in PDRIVER_OBJECT DriverObject, 387 __in PVOID ClientIdentificationAddress 388 ) 389 { 390 return IoGetDriverObjectExtension(DriverObject, 391 ClientIdentificationAddress); 392 } 393 394 __inline 395 NTSTATUS 396 Mx::MxAllocateDriverObjectExtension( 397 _In_ MdDriverObject DriverObject, 398 _In_ PVOID ClientIdentificationAddress, 399 _In_ ULONG DriverObjectExtensionSize, 400 // When successful, this always allocates already-aliased memory. 401 _Post_ _At_(*DriverObjectExtension, _When_(return==0, 402 __drv_aliasesMem __drv_allocatesMem(Mem) _Post_notnull_)) 403 _When_(return == 0, _Outptr_result_bytebuffer_(DriverObjectExtensionSize)) 404 PVOID *DriverObjectExtension 405 ) 406 { 407 return IoAllocateDriverObjectExtension(DriverObject, 408 ClientIdentificationAddress, 409 DriverObjectExtensionSize, 410 DriverObjectExtension); 411 } 412 413 __inline 414 MdDeviceObject 415 Mx::MxGetAttachedDeviceReference( 416 __in PDEVICE_OBJECT DriverObject 417 ) 418 { 419 return IoGetAttachedDeviceReference(DriverObject); 420 } 421 422 __inline 423 VOID 424 Mx::MxDeleteSymbolicLink( 425 __in PUNICODE_STRING Value 426 ) 427 { 428 IoDeleteSymbolicLink(Value); 429 } 430 431 __inline 432 VOID 433 Mx::MxDeleteNPagedLookasideList( 434 _In_ PNPAGED_LOOKASIDE_LIST LookasideList 435 ) 436 { 437 ExDeleteNPagedLookasideList(LookasideList); 438 } 439 440 __inline 441 VOID 442 Mx::MxDeletePagedLookasideList( 443 _In_ PPAGED_LOOKASIDE_LIST LookasideList 444 ) 445 { 446 ExDeletePagedLookasideList(LookasideList); 447 } 448 449 __inline 450 VOID 451 Mx::MxInitializeNPagedLookasideList( 452 _Out_ PNPAGED_LOOKASIDE_LIST Lookaside, 453 _In_opt_ PALLOCATE_FUNCTION Allocate, 454 _In_opt_ PFREE_FUNCTION Free, 455 _In_ ULONG Flags, 456 _In_ SIZE_T Size, 457 _In_ ULONG Tag, 458 _In_ USHORT Depth 459 ) 460 { 461 ExInitializeNPagedLookasideList(Lookaside, 462 Allocate, 463 Free, 464 Flags, 465 Size, 466 Tag, 467 Depth); 468 } 469 470 __inline 471 VOID 472 Mx::MxInitializePagedLookasideList( 473 _Out_ PPAGED_LOOKASIDE_LIST Lookaside, 474 _In_opt_ PALLOCATE_FUNCTION Allocate, 475 _In_opt_ PFREE_FUNCTION Free, 476 _In_ ULONG Flags, 477 _In_ SIZE_T Size, 478 _In_ ULONG Tag, 479 _In_ USHORT Depth 480 ) 481 { 482 ExInitializePagedLookasideList(Lookaside, 483 Allocate, 484 Free, 485 Flags, 486 Size, 487 Tag, 488 Depth); 489 } 490 491 __inline 492 VOID 493 Mx::MxDeleteDevice( 494 _In_ MdDeviceObject Device 495 ) 496 { 497 IoDeleteDevice(Device); 498 } 499 500 __inline 501 VOID 502 Mx::MxDetachDevice( 503 _Inout_ MdDeviceObject Device 504 ) 505 { 506 IoDetachDevice(Device); 507 } 508 509 __inline 510 MdDeviceObject 511 Mx::MxAttachDeviceToDeviceStack( 512 _In_ MdDeviceObject SourceDevice, 513 _In_ MdDeviceObject TargetDevice 514 ) 515 { 516 return IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice); 517 } 518 519 __inline 520 NTSTATUS 521 Mx::MxCreateDeviceSecure( 522 _In_ PDRIVER_OBJECT DriverObject, 523 _In_ ULONG DeviceExtensionSize, 524 _In_opt_ PUNICODE_STRING DeviceName, 525 _In_ DEVICE_TYPE DeviceType, 526 _In_ ULONG DeviceCharacteristics, 527 _In_ BOOLEAN Exclusive, 528 _In_ PCUNICODE_STRING DefaultSDDLString, 529 _In_opt_ LPCGUID DeviceClassGuid, 530 _Out_ MdDeviceObject *DeviceObject 531 ) 532 { 533 #ifndef __REACTOS__ // we don't have wdmsec.lib 534 return IoCreateDeviceSecure(DriverObject, 535 DeviceExtensionSize, 536 DeviceName, 537 DeviceType, 538 DeviceCharacteristics, 539 Exclusive, 540 DefaultSDDLString, 541 DeviceClassGuid, 542 DeviceObject); 543 #else 544 return IoCreateDevice( 545 DriverObject, 546 DeviceExtensionSize, 547 DeviceName, 548 DeviceType, 549 DeviceCharacteristics, 550 Exclusive, 551 DeviceObject); 552 #endif 553 } 554 555 __inline 556 NTSTATUS 557 Mx::MxCreateDevice( 558 _In_ PDRIVER_OBJECT DriverObject, 559 _In_ ULONG DeviceExtensionSize, 560 _In_opt_ PUNICODE_STRING DeviceName, 561 _In_ DEVICE_TYPE DeviceType, 562 _In_ ULONG DeviceCharacteristics, 563 _In_ BOOLEAN Exclusive, 564 _Out_ MdDeviceObject *DeviceObject 565 ) 566 { 567 return IoCreateDevice(DriverObject, 568 DeviceExtensionSize, 569 DeviceName, 570 DeviceType, 571 DeviceCharacteristics, 572 Exclusive, 573 DeviceObject); 574 575 } 576 577 __inline 578 NTSTATUS 579 Mx::MxCreateSymbolicLink( 580 _In_ PUNICODE_STRING SymbolicLinkName, 581 _In_ PUNICODE_STRING DeviceName 582 ) 583 { 584 return IoCreateSymbolicLink(SymbolicLinkName, DeviceName); 585 } 586 587 __inline 588 VOID 589 Mx::MxFlushQueuedDpcs( 590 ) 591 { 592 KeFlushQueuedDpcs(); 593 } 594 595 __inline 596 NTSTATUS 597 Mx::MxOpenKey( 598 _Out_ PHANDLE KeyHandle, 599 _In_ ACCESS_MASK DesiredAccess, 600 _In_ POBJECT_ATTRIBUTES ObjectAttributes 601 ) 602 { 603 return ZwOpenKey(KeyHandle, DesiredAccess, ObjectAttributes); 604 } 605 606 __inline 607 NTSTATUS 608 Mx::MxSetDeviceInterfaceState( 609 _In_ PUNICODE_STRING SymbolicLinkName, 610 _In_ BOOLEAN Enable 611 ) 612 { 613 return IoSetDeviceInterfaceState(SymbolicLinkName, Enable); 614 } 615 616 617 __inline 618 NTSTATUS 619 Mx::MxRegisterDeviceInterface( 620 _In_ PDEVICE_OBJECT PhysicalDeviceObject, 621 _In_ const GUID *InterfaceClassGuid, 622 _In_opt_ PUNICODE_STRING ReferenceString, 623 _Out_ PUNICODE_STRING SymbolicLinkName 624 ) 625 { 626 return IoRegisterDeviceInterface(PhysicalDeviceObject, 627 InterfaceClassGuid, 628 ReferenceString, 629 SymbolicLinkName); 630 } 631 632 __inline 633 NTSTATUS 634 Mx::MxDeleteKey( 635 _In_ HANDLE KeyHandle 636 ) 637 { 638 return ZwDeleteKey(KeyHandle); 639 } 640 641 __inline 642 VOID 643 Mx::MxInitializeMdl( 644 _In_ PMDL MemoryDescriptorList, 645 _In_ PVOID BaseVa, 646 _In_ SIZE_T Length 647 ) 648 { 649 MmInitializeMdl(MemoryDescriptorList, BaseVa, Length); 650 } 651 652 __inline 653 PVOID 654 Mx::MxGetMdlVirtualAddress( 655 _In_ PMDL Mdl 656 ) 657 { 658 return MmGetMdlVirtualAddress(Mdl); 659 } 660 661 __inline 662 VOID 663 Mx::MxBuildPartialMdl( 664 _In_ PMDL SourceMdl, 665 _Inout_ PMDL TargetMdl, 666 _In_ PVOID VirtualAddress, 667 _In_ ULONG Length 668 ) 669 { 670 IoBuildPartialMdl(SourceMdl, 671 TargetMdl, 672 VirtualAddress, 673 Length 674 ); 675 } 676 677 __inline 678 VOID 679 Mx::MxQuerySystemTime( 680 _Out_ PLARGE_INTEGER CurrentTime 681 ) 682 { 683 KeQuerySystemTime(CurrentTime); 684 } 685 686 __inline 687 NTSTATUS 688 Mx::MxSetValueKey( 689 _In_ HANDLE KeyHandle, 690 _In_ PUNICODE_STRING ValueName, 691 _In_opt_ ULONG TitleIndex, 692 _In_ ULONG Type, 693 _In_opt_ PVOID Data, 694 _In_ ULONG DataSize 695 ) 696 { 697 return ZwSetValueKey(KeyHandle, 698 ValueName, 699 TitleIndex, 700 Type, 701 Data, 702 DataSize 703 ); 704 } 705 706 __inline 707 NTSTATUS 708 Mx::MxQueryValueKey( 709 _In_ HANDLE KeyHandle, 710 _In_ PUNICODE_STRING ValueName, 711 _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, 712 _Out_opt_ PVOID KeyValueInformation, 713 _In_ ULONG Length, 714 _Out_ PULONG ResultLength 715 ) 716 { 717 return ZwQueryValueKey(KeyHandle, 718 ValueName, 719 KeyValueInformationClass, 720 KeyValueInformation, 721 Length, 722 ResultLength 723 ); 724 } 725 726 __inline 727 NTSTATUS 728 Mx::MxReferenceObjectByHandle( 729 __in HANDLE Handle, 730 __in ACCESS_MASK DesiredAccess, 731 __in_opt POBJECT_TYPE ObjectType, 732 __in KPROCESSOR_MODE AccessMode, 733 __out PVOID *Object, 734 __out_opt POBJECT_HANDLE_INFORMATION HandleInformation 735 ) 736 { 737 return ObReferenceObjectByHandle( 738 Handle, 739 DesiredAccess, 740 ObjectType, 741 AccessMode, 742 Object, 743 HandleInformation); 744 } 745 746 __inline 747 NTSTATUS 748 Mx::MxUnRegisterPlugPlayNotification( 749 __in __drv_freesMem(Pool) PVOID NotificationEntry 750 ) 751 { 752 return IoUnregisterPlugPlayNotification(NotificationEntry); 753 } 754 755 756 __inline 757 NTSTATUS 758 Mx::MxClose( 759 __in HANDLE Handle 760 ) 761 { 762 return ZwClose(Handle); 763 } 764 765 __inline 766 KIRQL 767 Mx::MxAcquireInterruptSpinLock( 768 _Inout_ PKINTERRUPT Interrupt 769 ) 770 { 771 return KeAcquireInterruptSpinLock(Interrupt); 772 } 773 774 __inline 775 VOID 776 Mx::MxReleaseInterruptSpinLock( 777 _Inout_ PKINTERRUPT Interrupt, 778 _In_ KIRQL OldIrql 779 ) 780 { 781 KeReleaseInterruptSpinLock(Interrupt, OldIrql); 782 } 783 784 __inline 785 BOOLEAN 786 Mx::MxInsertQueueDpc( 787 __inout PRKDPC Dpc, 788 __in_opt PVOID SystemArgument1, 789 __in_opt PVOID SystemArgument2 790 ) 791 { 792 return KeInsertQueueDpc(Dpc, SystemArgument1, SystemArgument2); 793 } 794 795 796