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
IsPoolTrackingOn_FX_DRIVER_GLOBALS215     IsPoolTrackingOn(
216         VOID
217         )
218     {
219         return (FxPoolTrackingOn) ? TRUE : FALSE;
220     }
221 
222     BOOLEAN
IsObjectDebugOn_FX_DRIVER_GLOBALS223     IsObjectDebugOn(
224         VOID
225         )
226     {
227         if (FxVerifierHandle) {
228             return TRUE;
229         }
230         else {
231             return FALSE;
232         }
233     }
234 
235     VOID
SetVerifierState_FX_DRIVER_GLOBALS236     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
IsVerificationEnabled_FX_DRIVER_GLOBALS286     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
IsDownlevelVerificationEnabled_FX_DRIVER_GLOBALS314     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 
__bcount(Size)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 
__bcount(Size)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
GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)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
FxIsClassExtension(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in PFX_DRIVER_GLOBALS ExtDriverGlobals)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
FxIsEqualGuid(__in CONST GUID * Lhs,__in CONST GUID * Rhs)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
FxSizeTMax(__in size_t A,__in size_t B)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
FxSizeTMin(__in size_t A,__in size_t B)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
FxInterlockedIncrementFloor(__inout LONG volatile * Target,__in LONG Floor)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
FxInterlockedIncrementGTZero(__inout LONG volatile * Target)1045 FxInterlockedIncrementGTZero(
1046     __inout LONG  volatile *Target
1047     )
1048 {
1049     return FxInterlockedIncrementFloor(Target, 0);
1050 }
1051 
1052 __inline
1053 ULONG
FxRandom(__inout PULONG RandomSeed)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
FxIsPassiveLevelInterruptSupported(VOID)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
IsOsVersionGreaterThanOrEqualTo(__in ULONG Major,__in ULONG Minor)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