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