1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxGlobals.h 8 9 Abstract: 10 11 This module contains globals definitions for the frameworks. 12 13 Author: 14 15 16 17 18 Environment: 19 20 Both kernel and user mode 21 22 Revision History: 23 24 Made it mode agnostic 25 Moved km specific portions to FxGlobalsKm.h 26 27 28 29 30 31 32 33 34 35 New failure paths: 36 AllocatedTagTrackersLock initialization - 37 If this fails we free debug extensions structure and not use it 38 ThreadTableLock initialization - 39 If this fails we turn off lock verification 40 FxDriverGlobalsListLock initialization - 41 If this fails we fail FxLibraryGlobalsCommission 42 43 --*/ 44 45 #ifndef _FXGLOBALS_H 46 #define _FXGLOBALS_H 47 48 #include "wdfglobals.h" 49 #include <debug.h> 50 51 // REACTOS 52 #define ROSWDFNOTIMPLEMENTED (DbgPrint("(%s:%d) ReactOS KMDF: %s not implemented\n", __RELFILE__, __LINE__, __FUNCTION__)) 53 // REACTOS 54 55 #ifdef __cplusplus 56 extern "C" { 57 #endif 58 59 struct FxLibraryGlobalsType; 60 61 class CWudfDriverGlobals; //UMDF driver globals 62 63 // 64 // NOTE: any time you add a value to this enum, you must add a field to the 65 // union in FxObjectDebugInfo. 66 // 67 enum FxObjectDebugInfoFlags { 68 FxObjectDebugTrackReferences = 0x0001, 69 }; 70 71 typedef enum FxTrackPowerOption : UCHAR { 72 FxTrackPowerNone = 0, 73 FxTrackPowerRefs, 74 FxTrackPowerRefsAndStack, 75 FxTrackPowerMaxValue 76 } FxTrackPowerOption; 77 78 typedef enum FxVerifierDownlevelOption { 79 NotOkForDownLevel = 0, 80 OkForDownLevel = 1, 81 } FxVerifierDownLevelOption; 82 83 typedef enum WaitSignalFlags { 84 WaitSignalBreakUnderVerifier = 0x01, 85 WaitSignalBreakUnderDebugger = 0x02, 86 WaitSignalAlwaysBreak = 0x04 87 } WaitSignalFlags; 88 89 90 struct FxObjectDebugInfo { 91 // 92 // FX_OBJECT_TYPES enum value 93 // 94 USHORT ObjectType; 95 96 union { 97 // 98 // Combo of values from FxObjectDebugInfoFlags 99 // 100 USHORT DebugFlags; 101 102 // 103 // Break out of DebugFlags as individual fields. This is used by the 104 // debugger extension to reference the values w/out knowing the actual 105 // enum values. 106 // 107 struct { 108 USHORT TrackReferences : 1; 109 } Bits; 110 } u; 111 }; 112 113 struct FxDriverGlobalsDebugExtension { 114 // 115 // Debug information per object. List is sorted by 116 // FxObjectDebugInfo::ObjectType, length is the same as FxObjectsInfo. 117 // 118 FxObjectDebugInfo* ObjectDebugInfo; 119 120 // 121 // Track allocated Mdls only in kernel mode version 122 // 123 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 124 FxAllocatedMdls AllocatedMdls; 125 126 KSPIN_LOCK AllocatedMdlsLock; 127 #endif 128 129 // 130 // List of all allocated tag trackers for this driver. This is used to keep 131 // track of orphaned objects due to leaked reference counts in the debugger 132 // extension. 133 // 134 LIST_ENTRY AllocatedTagTrackersListHead; 135 136 // 137 // Synchronizes access to AllocatedTagTrackersListHead 138 // 139 MxLock AllocatedTagTrackersLock; 140 141 // 142 // Whether we track power references for WDFDEVICE objects 143 // and optionally capture stack frames. 144 // 145 FxTrackPowerOption TrackPower; 146 }; 147 148 // 149 // A telemetry context that is allocated if the telemetry provider is enabled. 150 // 151 typedef struct _FX_TELEMETRY_CONTEXT{ 152 // 153 // A GUID representing the driver session 154 // 155 GUID DriverSessionGUID; 156 157 // 158 // A general purpose bitmap that can be used 159 // by various telemetry events that may want to 160 // fire once per driver session. 161 // 162 volatile LONG DoOnceFlagsBitmap; 163 } FX_TELEMETRY_CONTEXT, *PFX_TELEMETRY_CONTEXT; 164 165 typedef struct _FX_DRIVER_GLOBALS { 166 public: 167 ULONG 168 __inline 169 AddRef( 170 __in_opt PVOID Tag = NULL, 171 __in LONG Line = 0, 172 __in_opt PSTR File = NULL 173 ) 174 { 175 ULONG c; 176 177 UNREFERENCED_PARAMETER(Tag); 178 UNREFERENCED_PARAMETER(Line); 179 UNREFERENCED_PARAMETER(File); 180 181 c = InterlockedIncrement(&Refcnt); 182 183 // 184 // Catch the transition from 0 to 1. Since the RefCount starts off at 1, 185 // we should never have to increment to get to this value. 186 // 187 ASSERT(c > 1); 188 return c; 189 } 190 191 ULONG 192 __inline 193 Release( 194 __in_opt PVOID Tag = NULL, 195 __in LONG Line = 0, 196 __in_opt PSTR File = NULL 197 ) 198 { 199 ULONG c; 200 201 UNREFERENCED_PARAMETER(Tag); 202 UNREFERENCED_PARAMETER(Line); 203 UNREFERENCED_PARAMETER(File); 204 205 c = InterlockedDecrement(&Refcnt); 206 ASSERT((LONG)c >= 0); 207 if (c == 0) { 208 DestroyEvent.Set(); 209 } 210 211 return c; 212 } 213 214 BOOLEAN 215 IsPoolTrackingOn( 216 VOID 217 ) 218 { 219 return (FxPoolTrackingOn) ? TRUE : FALSE; 220 } 221 222 BOOLEAN 223 IsObjectDebugOn( 224 VOID 225 ) 226 { 227 if (FxVerifierHandle) { 228 return TRUE; 229 } 230 else { 231 return FALSE; 232 } 233 } 234 235 VOID 236 SetVerifierState( 237 __in BOOLEAN State 238 ) 239 { 240 // 241 // Master switch 242 // 243 FxVerifierOn = State; 244 245 FxVerifierHandle = State; 246 FxVerifierIO = State; 247 FxVerifierLock = State; 248 FxPoolTrackingOn = State; 249 250 // 251 // Following two can be overridden by the registry settings 252 // WDFVERIFY matches the state of the verifier. 253 // 254 FxVerifyOn = State; 255 FxVerifierDbgBreakOnError = State; 256 FxVerifierDbgBreakOnDeviceStateError = FALSE; 257 258 // 259 // Set the public flags for consumption by client drivers. 260 // 261 if (State) { 262 Public.DriverFlags |= (WdfVerifyOn | WdfVerifierOn); 263 } 264 } 265 266 _Must_inspect_result_ 267 BOOLEAN 268 IsVersionGreaterThanOrEqualTo( 269 __in ULONG Major, 270 __in ULONG Minor 271 ); 272 273 _Must_inspect_result_ 274 BOOLEAN 275 IsCorrectVersionRegistered( 276 _In_ PCUNICODE_STRING ServiceKeyName 277 ); 278 279 VOID 280 RegisterClientVersion( 281 _In_ PCUNICODE_STRING ServiceKeyName 282 ); 283 284 _Must_inspect_result_ 285 BOOLEAN 286 IsVerificationEnabled( 287 __in ULONG Major, 288 __in ULONG Minor, 289 __in FxVerifierDownlevelOption DownLevel 290 ) 291 { 292 // 293 // those verifier checks that are restricted to specific version can be 294 // applied to previous version drivers if driver opts-in by setting a 295 // reg key (whose value is stored in FxVerifyDownlevel) 296 // 297 if (FxVerifierOn && 298 (IsVersionGreaterThanOrEqualTo(Major, Minor) || 299 (DownLevel ? FxVerifyDownlevel : FALSE))) { 300 return TRUE; 301 } 302 else { 303 return FALSE; 304 } 305 } 306 307 // 308 // To be used in code path where it is already determined that the driver 309 // is down-level, otherwise use IsVerificationEnabled. 310 // 311 __inline 312 _Must_inspect_result_ 313 BOOLEAN 314 IsDownlevelVerificationEnabled( 315 ) 316 { 317 return FxVerifyDownlevel; 318 } 319 320 VOID 321 WaitForSignal( 322 __in MxEvent* Event, 323 __in PCSTR ReasonForWaiting, 324 __in PVOID Handle, 325 __in ULONG WarningTimeoutInSec, 326 __in ULONG WaitSignalFlags 327 ); 328 329 _Must_inspect_result_ 330 BOOLEAN 331 IsDebuggerAttached( 332 VOID 333 ); 334 335 public: 336 // 337 // Link list of driver FxDriverGlobals on this WDF Version. 338 // 339 LIST_ENTRY Linkage; 340 341 // 342 // Reference count is operated on with interlocked operations 343 // 344 LONG Refcnt; 345 346 // 347 // This event is signaled when globals can be freed. Unload thread waits 348 // on this event to make sure driver's threads are done and driver unload 349 // can proceed. 350 // 351 MxEvent DestroyEvent; 352 353 // 354 // Mask to XOR all outgoing handles against 355 // 356 ULONG_PTR WdfHandleMask; 357 358 // 359 // If verifier is on, this is the count of allocations 360 // to fail at 361 // 362 LONG WdfVerifierAllocateFailCount; 363 364 // 365 // Tag to be used for allocations on behalf of the driver writer. This is 366 // based off of the service name (which might be different than the binary 367 // name). 368 // 369 ULONG Tag; 370 371 // 372 // Backpointer to Fx driver object 373 // 374 FxDriver* Driver; 375 376 FxDriverGlobalsDebugExtension* DebugExtension; 377 378 FxLibraryGlobalsType* LibraryGlobals; 379 380 // 381 // WDF internal In-Flight Recorder (IFR) log 382 // 383 PVOID WdfLogHeader; 384 385 // 386 // The driver's memory pool header 387 // 388 FX_POOL FxPoolFrameworks; 389 390 // 391 // Framworks Pool Tracking 392 // 393 BOOLEAN FxPoolTrackingOn; 394 395 // 396 // FxVerifierLock per driver state 397 // 398 MxLock ThreadTableLock; 399 400 PLIST_ENTRY ThreadTable; 401 402 // 403 // Embedded pointer to driver's WDF_BIND_INFO structure (in stub) 404 // 405 PWDF_BIND_INFO WdfBindInfo; 406 407 // 408 // The base address of the image. 409 // 410 PVOID ImageAddress; 411 412 // 413 // The size of the image. 414 // 415 ULONG ImageSize; 416 417 // 418 // Top level verifier flag. 419 // 420 BOOLEAN FxVerifierOn; 421 422 // 423 // Apply latest-version-restricted verifier checks to downlevel drivers. 424 // Drivers set this value in registry. 425 // 426 BOOLEAN FxVerifyDownlevel; 427 428 // 429 // Breakpoint on errors. 430 // 431 BOOLEAN FxVerifierDbgBreakOnError; 432 433 // 434 // Breakpoint on device state errors. 435 // 436 BOOLEAN FxVerifierDbgBreakOnDeviceStateError; 437 438 // 439 // Handle verifier. 440 // 441 BOOLEAN FxVerifierHandle; 442 443 // 444 // I/O verifier. 445 // 446 BOOLEAN FxVerifierIO; 447 448 // 449 // Lock verifier. 450 // 451 BOOLEAN FxVerifierLock; 452 453 // 454 // Not a verifier option. Rather, controls whether WDFVERIFY macros are 455 // live. 456 // 457 BOOLEAN FxVerifyOn; 458 459 // 460 // Capture IFR Verbose messages. 461 // 462 BOOLEAN FxVerboseOn; 463 464 // 465 // Parent queue presented requests (to device). 466 // 467 BOOLEAN FxRequestParentOptimizationOn; 468 469 // 470 // Enable/Disable support for device simulation framework (DSF). 471 // 472 BOOLEAN FxDsfOn; 473 474 // 475 // Force copy of IFR data to mini-dump when a bugcheck happens. 476 // 477 BOOLEAN FxForceLogsInMiniDump; 478 479 // 480 // TRUE to enable run-time driver tracking. The dump callback logic 481 // uses this info for finding the right log to write in the minidump. 482 // 483 BOOLEAN FxTrackDriverForMiniDumpLog; 484 485 // 486 // TRUE if compiled for user-mode 487 // 488 BOOLEAN IsUserModeDriver; 489 490 // 491 // Remove lock options, these are also specified through 492 // WdfDeviceInitSetRemoveLockOptions. 493 // 494 ULONG RemoveLockOptionFlags; 495 496 // 497 // Bug check callback data for kernel mode only 498 499 500 501 // 502 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 503 // 504 // 0-based index into the BugCheckDriverInfo holding this driver info. 505 // 506 ULONG BugCheckDriverInfoIndex; 507 508 // 509 // Bug check callback record for processing bugchecks. 510 // 511 KBUGCHECK_REASON_CALLBACK_RECORD BugCheckCallbackRecord; 512 513 #endif 514 515 // 516 // Enhanced Verifier Options. 517 // 518 ULONG FxEnhancedVerifierOptions; 519 520 // 521 // If FxVerifierDbgBreakOnError is true, WaitForSignal interrupts the 522 // execution of the system after waiting for the specified number 523 // of seconds. Developer will have an opportunity to validate the state 524 // of the driver when breakpoint is hit. Developer can continue to wait 525 // by entering 'g' in the debugger. 526 // 527 ULONG FxVerifierDbgWaitForSignalTimeoutInSec; 528 529 // 530 // Timeout used by the wake interrupt ISR in WaitForSignal to catch 531 // scenarios where the interrupt ISR is blocked because the device stack 532 // is taking too long to power up 533 // 534 ULONG DbgWaitForWakeInterruptIsrTimeoutInSec; 535 536 #if (FX_CORE_MODE==FX_CORE_USER_MODE) 537 CWudfDriverGlobals * UfxDriverGlobals; 538 #endif 539 540 PFX_TELEMETRY_CONTEXT TelemetryContext; 541 542 // 543 // The public version of WDF_DRIVER_GLOBALS 544 // 545 DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) WDF_DRIVER_GLOBALS Public; 546 547 } FX_DRIVER_GLOBALS, *PFX_DRIVER_GLOBALS; 548 549 __bcount(Size) 550 PVOID 551 FORCEINLINE 552 FxPoolAllocate( 553 __in PFX_DRIVER_GLOBALS Globals, 554 __in POOL_TYPE Type, 555 __in size_t Size 556 ) 557 { 558 // 559 // Always pass in the return address, regardless of the value of 560 // Globals->WdfPoolTrackingOn. 561 // 562 return FxPoolAllocator( 563 Globals, 564 &Globals->FxPoolFrameworks, 565 Type, 566 Size, 567 Globals->Tag, 568 _ReturnAddress() 569 ); 570 } 571 572 __bcount(Size) 573 PVOID 574 FORCEINLINE 575 FxPoolAllocateWithTag( 576 __in PFX_DRIVER_GLOBALS Globals, 577 __in POOL_TYPE Type, 578 __in size_t Size, 579 __in ULONG Tag 580 ) 581 { 582 return FxPoolAllocator( 583 Globals, 584 &Globals->FxPoolFrameworks, 585 Type, 586 Size, 587 Tag, 588 Globals->FxPoolTrackingOn ? _ReturnAddress() : NULL 589 ); 590 } 591 592 // 593 // Get FxDriverGlobals from api's DriverGlobals 594 // 595 __inline 596 PFX_DRIVER_GLOBALS 597 GetFxDriverGlobals( 598 __in PWDF_DRIVER_GLOBALS DriverGlobals 599 ) 600 { 601 return CONTAINING_RECORD( DriverGlobals, FX_DRIVER_GLOBALS, Public ); 602 } 603 604 typedef struct _WDF_DRIVER_CONFIG *PWDF_DRIVER_CONFIG; 605 606 #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE)) 607 VOID 608 LockVerifierSection( 609 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals, 610 _In_ PCUNICODE_STRING RegistryPath 611 ); 612 613 VOID 614 UnlockVerifierSection( 615 _In_ PFX_DRIVER_GLOBALS FxDriverGlobals 616 ); 617 #endif 618 619 BOOLEAN 620 IsWindowsVerifierOn( 621 _In_ MdDriverObject DriverObject 622 ); 623 624 _Must_inspect_result_ 625 NTSTATUS 626 FxInitialize( 627 __inout PFX_DRIVER_GLOBALS FxDriverGlobals, 628 __in MdDriverObject DriverObject, 629 __in PCUNICODE_STRING RegistryPath, 630 __in_opt PWDF_DRIVER_CONFIG DriverConfig //optional in user mode 631 ); 632 633 VOID 634 FxDestroy( 635 __in PFX_DRIVER_GLOBALS FxDriverGlobals 636 ); 637 638 _Must_inspect_result_ 639 NTSTATUS 640 FxLibraryGlobalsCommission( 641 VOID 642 ); 643 644 VOID 645 FxLibraryGlobalsDecommission( 646 VOID 647 ); 648 649 VOID 650 FxCheckAssumptions( 651 VOID 652 ); 653 654 void 655 FxVerifierLockInitialize( 656 __in PFX_DRIVER_GLOBALS FxDriverGlobals 657 ); 658 659 void 660 FxVerifierLockDestroy( 661 __in PFX_DRIVER_GLOBALS FxDriverGlobals 662 ); 663 664 _Must_inspect_result_ 665 BOOLEAN 666 FxVerifierGetTrackReferences( 667 __in FxObjectDebugInfo* DebugInfo, 668 __in WDFTYPE ObjectType 669 ); 670 671 PCSTR 672 FxObjectTypeToHandleName( 673 __in WDFTYPE ObjectType 674 ); 675 676 typedef 677 NTSTATUS 678 (*PFN_WMI_QUERY_TRACE_INFORMATION)( 679 __in TRACE_INFORMATION_CLASS TraceInformationClass, 680 __out PVOID TraceInformation, 681 __in ULONG TraceInformationLength, 682 __out_opt PULONG RequiredLength, 683 __in_opt PVOID Buffer 684 ); 685 686 typedef 687 NTSTATUS 688 (*PFN_WMI_TRACE_MESSAGE_VA)( 689 __in TRACEHANDLE LoggerHandle, 690 __in ULONG MessageFlags, 691 __in LPGUID MessageGuid, 692 __in USHORT MessageNumber, 693 __in va_list MessageArgList 694 ); 695 696 enum FxMachineSleepStates { 697 FxMachineS1Index = 0, 698 FxMachineS2Index, 699 FxMachineS3Index, 700 FxMachineSleepStatesMax, 701 }; 702 703 // 704 // Private Globals for the entire DLL 705 706 // 707 struct FxLibraryGlobalsType { 708 709 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 710 711 // 712 // The driver object for the library. 713 714 715 716 717 718 // 719 PDRIVER_OBJECT DriverObject; 720 721 // 722 // As long as this device object is around, the library cannot be unloaded. 723 // This prevents the following scenario from unloading the service 724 // 1 wdfldr.sys loads the library 725 // 2 user tries to run "net stop <service>" while there are outstanding clients 726 // through wdfldr 727 // 728 PDEVICE_OBJECT LibraryDeviceObject; 729 730 PFN_IO_CONNECT_INTERRUPT_EX IoConnectInterruptEx; 731 732 PFN_IO_DISCONNECT_INTERRUPT_EX IoDisconnectInterruptEx; 733 734 PFN_KE_QUERY_ACTIVE_PROCESSORS KeQueryActiveProcessors; 735 736 PFN_KE_SET_TARGET_PROCESSOR_DPC KeSetTargetProcessorDpc; 737 738 PFN_KE_SET_COALESCABLE_TIMER KeSetCoalescableTimer; 739 740 PFN_IO_UNREGISTER_PLUGPLAY_NOTIFICATION_EX IoUnregisterPlugPlayNotificationEx; 741 742 PFN_POX_REGISTER_DEVICE PoxRegisterDevice; 743 744 PFN_POX_START_DEVICE_POWER_MANAGEMENT PoxStartDevicePowerManagement; 745 746 PFN_POX_UNREGISTER_DEVICE PoxUnregisterDevice; 747 748 PFN_POX_ACTIVATE_COMPONENT PoxActivateComponent; 749 750 PFN_POX_IDLE_COMPONENT PoxIdleComponent; 751 752 PFN_POX_REPORT_DEVICE_POWERED_ON PoxReportDevicePoweredOn; 753 754 PFN_POX_COMPLETE_IDLE_STATE PoxCompleteIdleState; 755 756 PFN_POX_COMPLETE_IDLE_CONDITION PoxCompleteIdleCondition; 757 758 PFN_POX_COMPLETE_DEVICE_POWER_NOT_REQUIRED PoxCompleteDevicePowerNotRequired; 759 760 PFN_POX_SET_DEVICE_IDLE_TIMEOUT PoxSetDeviceIdleTimeout; 761 762 PFN_IO_REPORT_INTERRUPT_ACTIVE IoReportInterruptActive; 763 764 PFN_IO_REPORT_INTERRUPT_INACTIVE IoReportInterruptInactive; 765 766 PFN_VF_CHECK_NX_POOL_TYPE VfCheckNxPoolType; 767 768 #endif 769 770 RTL_OSVERSIONINFOEXW OsVersionInfo; 771 772 MxLockNoDynam FxDriverGlobalsListLock; 773 774 LIST_ENTRY FxDriverGlobalsList; 775 776 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 777 // 778 // Index to first free entry in BugCheckDriverInfo array. 779 // 780 ULONG BugCheckDriverInfoIndex; 781 782 // 783 // # of entries in BugCheckDriverInfo array. 784 // 785 ULONG BugCheckDriverInfoCount; 786 787 // 788 // Array of info about loaded driver. The library bugcheck callback 789 // writes this data into the minidump. 790 // 791 PFX_DUMP_DRIVER_INFO_ENTRY BugCheckDriverInfo; 792 793 // 794 // Library bug-check callback record for processing bugchecks. 795 // 796 KBUGCHECK_REASON_CALLBACK_RECORD BugCheckCallbackRecord; 797 798 BOOLEAN ProcessorGroupSupport; 799 800 #endif 801 // 802 // WPP tracing. 803 // 804 BOOLEAN InternalTracingInitialized; 805 806 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 807 // 808 // The following field is used by the debug dump callback routine for 809 // finding which driver's dump log file to write in the minidump if an 810 // exact match is not found. 811 // 812 FX_DRIVER_TRACKER_CACHE_AWARE DriverTracker; 813 814 // 815 // Best driver match for the mini-dump log. 816 // 817 PFX_DRIVER_GLOBALS BestDriverForDumpLog; 818 #endif 819 820 BOOLEAN PassiveLevelInterruptSupport; 821 822 // 823 // TRUE if compiled for user-mode 824 // 825 BOOLEAN IsUserModeFramework; 826 827 // 828 829 830 831 832 833 834 // 835 836 BOOLEAN MachineSleepStates[FxMachineSleepStatesMax]; 837 838 #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE) 839 // 840 // used for locking/unlocking Enhanced-verifier image section 841 // 842 PVOID VerifierSectionHandle; 843 844 // 845 // This keeps track of the # of times we pinned the paged memory down. 846 // This is only used to aid debugging. 847 // 848 volatile LONG VerifierSectionHandleRefCount; 849 850 // 851 // Routines provided by the kernel SystemTraceProvider for perf 852 // tracing of WDF operations. The size member of this structure 853 // allows versioning across multiple OS versions. 854 // 855 //PWMI_WDF_NOTIFY_ROUTINES PerfTraceRoutines; __REACTOS__ 856 PVOID PerfTraceRoutines; 857 858 // 859 // PerfTraceRoutines points here if the SystemTraceProvider failed 860 // to provide trace routines. 861 // 862 //WMI_WDF_NOTIFY_ROUTINES DummyPerfTraceRoutines; __REACTOS__ 863 PVOID DummyPerfTraceRoutines; 864 865 #endif 866 867 // 868 // Registry setting to disable IFR on low-memory systems. 869 // 870 BOOLEAN IfrDisabled; 871 }; 872 873 extern FxLibraryGlobalsType FxLibraryGlobals; 874 875 876 typedef struct _FX_OBJECT_INFO { 877 // 878 // The name of the object, ie "FxObject" 879 // 880 const CHAR* Name; 881 882 // 883 // The name of the external WDF handle that represents the object, ie 884 // WDFDEVICE. If the object does not have an external handle, this field 885 // may be NULL. 886 // 887 const CHAR* HandleName; 888 889 // 890 // The minimum size of the object, ie sizeof(FxObject). There are objects 891 // which allocate more than their sizeof() length. 892 // 893 USHORT Size; 894 895 // 896 // FX_OBJECT_TYPES value 897 // 898 USHORT ObjectType; 899 900 } FX_OBJECT_INFO, *PFX_OBJECT_INFO; 901 902 // 903 // Define to declare an internal entry. An internal entry has no external WDF 904 // handle. 905 // 906 #define FX_INTERNAL_OBJECT_INFO_ENTRY(_obj, _type) \ 907 { #_obj, NULL, sizeof(_obj), _type, } 908 909 // 910 // Define to declare an external entry. An external entry has an external WDF 911 // handle. 912 // 913 // By casting #_handletype to a (_handletype), we make sure that _handletype is 914 // actually a valid WDF handle name. The cast forces the parameter to be 915 // evaluated as true handle type vs a string (ie the # preprocesor operator). 916 // For instance, this would catch the following error: 917 // 918 // FX_EXTERNAL_OBJECT_INFO_ENTRY(FxDevice, FX_TYPE_DEVICE, WDFDEVICES), 919 // 920 // because the statement would evaluate to (const CHAR*) (WDFDEVICES) "WDFDEVICES" 921 // and WDFDEVICES is not a valid type (WDFDEVICE is though). 922 // 923 #define FX_EXTERNAL_OBJECT_INFO_ENTRY(_obj, _type, _handletype) \ 924 { #_obj, \ 925 (const CHAR*) (_handletype) #_handletype, \ 926 sizeof(_obj), \ 927 _type, \ 928 } 929 930 _Must_inspect_result_ 931 BOOLEAN 932 FxVerifyObjectTypeInTable( 933 __in USHORT ObjectType 934 ); 935 936 VOID 937 FxFlushQueuedDpcs( 938 VOID 939 ); 940 941 VOID 942 FxFreeAllocatedMdlsDebugInfo( 943 __in FxDriverGlobalsDebugExtension* DebugExtension 944 ); 945 946 // 947 948 949 950 951 952 953 954 955 956 957 958 959 960 // 961 962 _Must_inspect_result_ 963 __inline 964 BOOLEAN 965 FxIsClassExtension( 966 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 967 __in PFX_DRIVER_GLOBALS ExtDriverGlobals 968 ) 969 { 970 return (FxDriverGlobals == ExtDriverGlobals) ? FALSE : TRUE; 971 } 972 973 974 _Must_inspect_result_ 975 BOOLEAN 976 __inline 977 FxIsEqualGuid( 978 __in CONST GUID* Lhs, 979 __in CONST GUID* Rhs 980 ) 981 { 982 return RtlCompareMemory(Lhs, Rhs, sizeof(GUID)) == sizeof(GUID); 983 } 984 985 __inline 986 size_t 987 FxSizeTMax( 988 __in size_t A, 989 __in size_t B 990 ) 991 { 992 return A > B ? A : B; 993 } 994 995 __inline 996 size_t 997 FxSizeTMin( 998 __in size_t A, 999 __in size_t B 1000 ) 1001 { 1002 return A < B ? A : B; 1003 } 1004 1005 __inline 1006 LONG 1007 FxInterlockedIncrementFloor( 1008 __inout LONG volatile *Target, 1009 __in LONG Floor 1010 ) 1011 { 1012 LONG startVal; 1013 LONG currentVal; 1014 1015 currentVal = *Target; 1016 1017 do { 1018 if (currentVal <= Floor) { 1019 return currentVal; 1020 } 1021 1022 startVal = currentVal; 1023 1024 // 1025 // currentVal will be the value that used to be Target if the exchange was made 1026 // or its current value if the exchange was not made. 1027 // 1028 currentVal = InterlockedCompareExchange(Target, startVal+1, startVal); 1029 1030 // 1031 // If startVal == currentVal, then no one updated Target in between the deref at the top 1032 // and the InterlockedCompareExchange afterward. 1033 // 1034 } while (startVal != currentVal); 1035 1036 // 1037 // startVal is the old value of Target. Since InterlockedIncrement returns the new 1038 // incremented value of Target, we should do the same here. 1039 // 1040 return startVal+1; 1041 } 1042 1043 __inline 1044 LONG 1045 FxInterlockedIncrementGTZero( 1046 __inout LONG volatile *Target 1047 ) 1048 { 1049 return FxInterlockedIncrementFloor(Target, 0); 1050 } 1051 1052 __inline 1053 ULONG 1054 FxRandom( 1055 __inout PULONG RandomSeed 1056 ) 1057 /*++ 1058 1059 Routine Description: 1060 1061 Simple threadsafe random number generator to use at DISPATCH_LEVEL 1062 (in kernel mode) because the system provided function RtlRandomEx 1063 can be called at only passive-level. 1064 1065 This function requires the user to provide a variable used to seed 1066 the generator, and it must be valid and initialized to some number. 1067 1068 Return Value: 1069 1070 ULONG 1071 1072 --*/ 1073 { 1074 *RandomSeed = *RandomSeed * 1103515245 + 12345; 1075 return (ULONG)(*RandomSeed / 65536) % 32768; 1076 } 1077 1078 _Must_inspect_result_ 1079 __inline 1080 BOOLEAN 1081 FxIsPassiveLevelInterruptSupported( 1082 VOID 1083 ) 1084 { 1085 // 1086 // Passive-level interrupt handling is supported in Win 8 and forward. 1087 // 1088 return FxLibraryGlobals.PassiveLevelInterruptSupport; 1089 } 1090 1091 __inline 1092 _Must_inspect_result_ 1093 BOOLEAN 1094 IsOsVersionGreaterThanOrEqualTo( 1095 __in ULONG Major, 1096 __in ULONG Minor 1097 ) 1098 { 1099 return ((FxLibraryGlobals.OsVersionInfo.dwMajorVersion > Major) || 1100 ((FxLibraryGlobals.OsVersionInfo.dwMajorVersion == Major) && 1101 (FxLibraryGlobals.OsVersionInfo.dwMinorVersion >= Minor))); 1102 } 1103 1104 #ifdef __cplusplus 1105 } 1106 #endif 1107 #endif // _FXGLOBALS_H 1108 1109