/*++ Copyright (c) Microsoft Corporation Module Name: FxGlobalsKm.h Abstract: This module contains kernel-mode specific globals definitions for the frameworks. For common definitions common between km and um please see FxGlobals.h Author: Environment: Kernel mode only Revision History: --*/ #ifdef __cplusplus extern "C" { #endif extern PCHAR WdfLdrType; #define WDF_LDR_STATIC_TYPE_STR "WdfStatic" // forward definitions typedef struct _FX_DRIVER_GLOBALS *PFX_DRIVER_GLOBALS; typedef struct _FX_DUMP_DRIVER_INFO_ENTRY *PFX_DUMP_DRIVER_INFO_ENTRY; struct FxMdlDebugInfo { PMDL Mdl; FxObject* Owner; PVOID Caller; }; #define NUM_MDLS_IN_INFO (16) struct FxAllocatedMdls { FxMdlDebugInfo Info[NUM_MDLS_IN_INFO]; ULONG Count; struct FxAllocatedMdls* Next; }; #define DDI_ENTRY_IMPERSONATION_OK() #define DDI_ENTRY() typedef BOOLEAN (STDCALL *PFN_KD_REFRESH)( ); typedef VOID (STDCALL *PFN_KE_FLUSH_QUEUED_DPCS)( VOID ); typedef NTSTATUS (STDCALL *PFN_IO_SET_COMPLETION_ROUTINE_EX)( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PIO_COMPLETION_ROUTINE CompletionRoutine, __in PVOID Context, __in BOOLEAN InvokeOnSuccess, __in BOOLEAN InvokeOnError, __in BOOLEAN InvokeOnCancel ); typedef BOOLEAN (STDCALL *PFN_KE_REGISTER_BUGCHECK_REASON_CALLBACK) ( __in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, __in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, __in KBUGCHECK_CALLBACK_REASON Reason, __in PUCHAR Component ); typedef BOOLEAN (STDCALL *PFN_KE_DEREGISTER_BUGCHECK_REASON_CALLBACK) ( __in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecords ); typedef NTSTATUS (STDCALL *PFN_IO_CONNECT_INTERRUPT_EX)( __inout PIO_CONNECT_INTERRUPT_PARAMETERS Parameters ); typedef NTSTATUS (STDCALL *PFN_IO_DISCONNECT_INTERRUPT_EX)( __in PIO_DISCONNECT_INTERRUPT_PARAMETERS Parameters ); typedef NTSTATUS (STDCALL *PFN_IO_CONNECT_INTERRUPT)( __out PKINTERRUPT *InterruptObject, __in PKSERVICE_ROUTINE ServiceRoutine, __in_opt PVOID ServiceContext, __in_opt PKSPIN_LOCK SpinLock, __in ULONG Vector, __in KIRQL Irql, __in KIRQL SynchronizeIrql, __in KINTERRUPT_MODE InterruptMode, __in BOOLEAN ShareVector, __in KAFFINITY ProcessorEnableMask, __in BOOLEAN FloatingSave ); typedef VOID (STDCALL *PFN_IO_DISCONNECT_INTERRUPT)( __in PKINTERRUPT InterruptObject ); typedef KIRQL (FASTCALL *PFN_KF_RAISE_IRQL) ( __in KIRQL NewIrql ); typedef VOID (FASTCALL *PFN_KF_LOWER_IRQL) ( __in KIRQL NewIrql ); typedef PSLIST_ENTRY (FASTCALL *PFN_INTERLOCKED_POP_ENTRY_SLIST)( __inout PSLIST_HEADER ListHead ); typedef PSLIST_ENTRY (FASTCALL *PFN_INTERLOCKED_PUSH_ENTRY_SLIST)( __inout PSLIST_HEADER ListHead, __inout PSLIST_ENTRY ListEntry ); typedef BOOLEAN (STDCALL *PFN_PO_GET_SYSTEM_WAKE)( __in PIRP Irp ); typedef VOID (STDCALL *PFN_PO_SET_SYSTEM_WAKE)( __inout PIRP Irp ); typedef KAFFINITY (STDCALL *PFN_KE_QUERY_ACTIVE_PROCESSORS)( VOID ); typedef VOID (STDCALL *PFN_KE_SET_TARGET_PROCESSOR_DPC)( __in PRKDPC Dpc, __in CCHAR Number ); typedef BOOLEAN (STDCALL *PFN_KE_SET_COALESCABLE_TIMER)( __inout PKTIMER Timer, __in LARGE_INTEGER DueTime, __in ULONG Period, __in ULONG TolerableDelay, __in_opt PKDPC Dpc ); typedef ULONG (STDCALL *PFN_KE_GET_CURRENT_PROCESSOR_NUMBER)( VOID ); typedef ULONG (STDCALL *PFN_KE_GET_CURRENT_PROCESSOR_NUMBER_EX)( __out_opt PPROCESSOR_NUMBER ProcNumber ); typedef ULONG (STDCALL *PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT_EX)( __in USHORT GroupNumber ); typedef ULONG (STDCALL *PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT)( VOID ); typedef BOOLEAN (STDCALL *PFN_KE_ARE_APCS_DISABLED)( VOID ); typedef ULONG (STDCALL *PFN_KE_GET_RECOMMENDED_SHARED_DATA_ALIGNMENT)( VOID ); typedef NTSTATUS (STDCALL *PFN_IO_UNREGISTER_PLUGPLAY_NOTIFICATION_EX)( __in PVOID NotificationEntry ); typedef NTSTATUS (STDCALL *PFN_POX_REGISTER_DEVICE) ( __in MdDeviceObject Pdo, __in PPO_FX_DEVICE PoxDevice, __out POHANDLE * Handle ); typedef VOID (STDCALL *PFN_POX_START_DEVICE_POWER_MANAGEMENT) ( __in POHANDLE Handle ); typedef VOID (STDCALL *PFN_POX_UNREGISTER_DEVICE) ( __in POHANDLE Handle ); typedef VOID (STDCALL *PFN_POX_ACTIVATE_COMPONENT) ( __in POHANDLE Handle, __in ULONG Component, __in ULONG Flags ); typedef VOID (STDCALL *PFN_POX_IDLE_COMPONENT) ( __in POHANDLE Handle, __in ULONG Component, __in ULONG Flags ); typedef VOID (STDCALL *PFN_POX_REPORT_DEVICE_POWERED_ON) ( __in POHANDLE Handle ); typedef VOID (STDCALL *PFN_POX_COMPLETE_IDLE_STATE) ( __in POHANDLE Handle, __in ULONG Component ); typedef VOID (STDCALL *PFN_POX_COMPLETE_IDLE_CONDITION) ( __in POHANDLE Handle, __in ULONG Component ); typedef VOID (STDCALL *PFN_POX_COMPLETE_DEVICE_POWER_NOT_REQUIRED) ( __in POHANDLE Handle ); typedef VOID (STDCALL *PFN_POX_SET_DEVICE_IDLE_TIMEOUT) ( __in POHANDLE Handle, __in ULONGLONG IdleTimeout ); typedef VOID (STDCALL *PFN_IO_REPORT_INTERRUPT_ACTIVE) ( _In_ PIO_REPORT_INTERRUPT_ACTIVE_STATE_PARAMETERS Parameters ); typedef VOID (STDCALL *PFN_IO_REPORT_INTERRUPT_INACTIVE) ( _In_ PIO_REPORT_INTERRUPT_ACTIVE_STATE_PARAMETERS Parameters ); typedef VOID (STDCALL *PFN_VF_CHECK_NX_POOL_TYPE) ( _In_ POOL_TYPE PoolType, _In_ PVOID CallingAddress, _In_ ULONG PoolTag ); VOID FxRegisterBugCheckCallback( __inout PFX_DRIVER_GLOBALS FxDriverGlobals, __in PDRIVER_OBJECT DriverObject ); VOID FxUnregisterBugCheckCallback( __inout PFX_DRIVER_GLOBALS FxDriverGlobals ); VOID FxInitializeBugCheckDriverInfo(); VOID FxUninitializeBugCheckDriverInfo(); VOID FxCacheBugCheckDriverInfo( __in PFX_DRIVER_GLOBALS FxDriverGlobals ); VOID FxPurgeBugCheckDriverInfo( __in PFX_DRIVER_GLOBALS FxDriverGlobals ); typedef struct _FX_DRIVER_TRACKER_CACHE_AWARE { // // Internal data types. // private: typedef struct _FX_DRIVER_TRACKER_ENTRY { volatile PFX_DRIVER_GLOBALS FxDriverGlobals; } FX_DRIVER_TRACKER_ENTRY, *PFX_DRIVER_TRACKER_ENTRY; // // Public interface. // public: _Must_inspect_result_ NTSTATUS Initialize(); VOID Uninitialize(); _Must_inspect_result_ NTSTATUS Register( __in PFX_DRIVER_GLOBALS FxDriverGlobals ); VOID Deregister( __in PFX_DRIVER_GLOBALS FxDriverGlobals ); // // Tracks the driver usage on the current processor. // KeGetCurrentProcessorNumberEx is called directly because the procgrp.lib // provides the downlevel support for Vista, XP and Win2000. // __inline VOID TrackDriver( __in PFX_DRIVER_GLOBALS FxDriverGlobals ) { ASSERT(m_PoolToFree != NULL); GetProcessorDriverEntryRef( KeGetCurrentProcessorIndex())->FxDriverGlobals = FxDriverGlobals; } // // Returns the tracked driver (globals) on the current processor. // KeGetCurrentProcessorNumberEx is called directly because the procgrp.lib // provides the downlevel support for Vista, XP and Win2000. // _Must_inspect_result_ __inline PFX_DRIVER_GLOBALS GetCurrentTrackedDriver() { PFX_DRIVER_GLOBALS fxDriverGlobals = NULL; ASSERT(m_PoolToFree != NULL); fxDriverGlobals = GetProcessorDriverEntryRef( KeGetCurrentProcessorIndex())->FxDriverGlobals; return fxDriverGlobals; } // // Helper functions. // private: // // Returns the per-processor cache-aligned driver usage ref structure for // given processor. // __inline PFX_DRIVER_TRACKER_ENTRY GetProcessorDriverEntryRef( __in ULONG Index ) { return ((PFX_DRIVER_TRACKER_ENTRY) (((PUCHAR)m_DriverUsage) + Index * m_EntrySize)); } // // Data members. // private: // // Pointer to array of cache-line aligned tracking driver structures. // PFX_DRIVER_TRACKER_ENTRY m_DriverUsage; // // Points to pool of per-proc tracking entries that needs to be freed. // PVOID m_PoolToFree; // // Size of each padded tracking driver structure. // ULONG m_EntrySize; // // Indicates # of entries in the array of tracking driver structures. // ULONG m_Number; } FX_DRIVER_TRACKER_CACHE_AWARE, *PFX_DRIVER_TRACKER_CACHE_AWARE; #include "fxglobals.h" // // This inline function tracks driver usage; This info is used by the // debug dump callback routine for selecting which driver's log to save // in the minidump. At this time we track the following OS to framework calls: // (a) IRP dispatch (general, I/O, PnP, WMI). // (b) Request's completion callbacks. // (c) Work Item's (& System Work Item's) callback handlers. // (d) Timer's callback handlers. // __inline VOID FX_TRACK_DRIVER( __in PFX_DRIVER_GLOBALS FxDriverGlobals ) { if (FxDriverGlobals->FxTrackDriverForMiniDumpLog) { FxLibraryGlobals.DriverTracker.TrackDriver(FxDriverGlobals); } } _Must_inspect_result_ __inline PVOID FxAllocateFromNPagedLookasideListNoTracking ( __in PNPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes (pops) the first entry from the specified nonpaged lookaside list. This function was added to allow request allocated by a lookaside list to be freed by ExFreePool and hence do no tracking of statistics. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (Entry == NULL) { Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } __inline VOID FxFreeToNPagedLookasideListNoTracking ( __in PNPAGED_LOOKASIDE_LIST Lookaside, __in PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified nonpaged lookaside list. This function was added to allow request allocated by a lookaside list to be freed by ExFreePool and hence do no tracking of statistics. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { (Lookaside->L.Free)(Entry); } else { InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); } } __inline PVOID FxAllocateFromNPagedLookasideList ( _In_ PNPAGED_LOOKASIDE_LIST Lookaside, _In_opt_ size_t ElementSize = 0 ) /*++ Routine Description: This function removes (pops) the first entry from the specified nonpaged lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; UNREFERENCED_PARAMETER(ElementSize); Lookaside->L.TotalAllocates += 1; Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (Entry == NULL) { Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } __inline VOID FxFreeToNPagedLookasideList ( __in PNPAGED_LOOKASIDE_LIST Lookaside, __in PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified nonpaged lookaside list. Arguments: Lookaside - Supplies a pointer to a nonpaged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { Lookaside->L.TotalFrees += 1; if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); } } _Must_inspect_result_ __inline PVOID FxAllocateFromPagedLookasideList ( __in PPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes (pops) the first entry from the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; Lookaside->L.TotalAllocates += 1; Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); if (Entry == NULL) { Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } __inline VOID FxFreeToPagedLookasideList ( __in PPAGED_LOOKASIDE_LIST Lookaside, __in PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { Lookaside->L.TotalFrees += 1; if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry); } } _Must_inspect_result_ __inline BOOLEAN FxIsProcessorGroupSupported( VOID ) { // // Groups are supported in Win 7 and forward. // return FxLibraryGlobals.ProcessorGroupSupport; } #ifdef __cplusplus } #endif