18a978a17SVictor Perevertkin 
28a978a17SVictor Perevertkin /*++
38a978a17SVictor Perevertkin 
48a978a17SVictor Perevertkin Copyright (c) Microsoft Corporation
58a978a17SVictor Perevertkin 
68a978a17SVictor Perevertkin Module Name:
78a978a17SVictor Perevertkin 
88a978a17SVictor Perevertkin     globals.cpp
98a978a17SVictor Perevertkin 
108a978a17SVictor Perevertkin Abstract:
118a978a17SVictor Perevertkin 
128a978a17SVictor Perevertkin     This contains all Driver Frameworks configuration globals.
138a978a17SVictor Perevertkin 
148a978a17SVictor Perevertkin Author:
158a978a17SVictor Perevertkin 
168a978a17SVictor Perevertkin 
178a978a17SVictor Perevertkin 
188a978a17SVictor Perevertkin 
198a978a17SVictor Perevertkin Environment:
208a978a17SVictor Perevertkin 
218a978a17SVictor Perevertkin     Both kernel and user mode
228a978a17SVictor Perevertkin 
238a978a17SVictor Perevertkin Revision History:
248a978a17SVictor Perevertkin 
258a978a17SVictor Perevertkin 
268a978a17SVictor Perevertkin 
278a978a17SVictor Perevertkin 
288a978a17SVictor Perevertkin 
298a978a17SVictor Perevertkin 
308a978a17SVictor Perevertkin 
318a978a17SVictor Perevertkin 
328a978a17SVictor Perevertkin 
338a978a17SVictor Perevertkin 
348a978a17SVictor Perevertkin 
358a978a17SVictor Perevertkin 
368a978a17SVictor Perevertkin 
378a978a17SVictor Perevertkin --*/
388a978a17SVictor Perevertkin 
398a978a17SVictor Perevertkin 
408a978a17SVictor Perevertkin #include "fxobjectpch.hpp"
418a978a17SVictor Perevertkin 
428a978a17SVictor Perevertkin // Tracing support
438a978a17SVictor Perevertkin extern "C" {
448a978a17SVictor Perevertkin #if defined(EVENT_TRACING)
458a978a17SVictor Perevertkin #include "globals.tmh"
468a978a17SVictor Perevertkin #endif
478a978a17SVictor Perevertkin }
488a978a17SVictor Perevertkin 
498a978a17SVictor Perevertkin extern "C" {
508a978a17SVictor Perevertkin 
518a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
528a978a17SVictor Perevertkin VOID
538a978a17SVictor Perevertkin VerifierPageLockHandle (
548a978a17SVictor Perevertkin     VOID
558a978a17SVictor Perevertkin     );
568a978a17SVictor Perevertkin #ifdef ALLOC_PRAGMA
578a978a17SVictor Perevertkin #pragma alloc_text(WDF_FX_VF_SECTION_NAME, VerifierPageLockHandle)
588a978a17SVictor Perevertkin #endif
598a978a17SVictor Perevertkin #endif
608a978a17SVictor Perevertkin 
618a978a17SVictor Perevertkin //
628a978a17SVictor Perevertkin // Private methods.
638a978a17SVictor Perevertkin //
648a978a17SVictor Perevertkin 
658a978a17SVictor Perevertkin VOID
668a978a17SVictor Perevertkin FxLibraryGlobalsQueryRegistrySettings(
678a978a17SVictor Perevertkin     VOID
688a978a17SVictor Perevertkin     );
698a978a17SVictor Perevertkin 
708a978a17SVictor Perevertkin VOID
718a978a17SVictor Perevertkin FxRegistrySettingsInitialize(
728a978a17SVictor Perevertkin     __inout PFX_DRIVER_GLOBALS FxDriverGlobals,
738a978a17SVictor Perevertkin     __in PCUNICODE_STRING RegistryPath,
748a978a17SVictor Perevertkin     __in BOOLEAN WindowsVerifierOn
758a978a17SVictor Perevertkin     );
768a978a17SVictor Perevertkin 
778a978a17SVictor Perevertkin _Must_inspect_result_
788a978a17SVictor Perevertkin FxObjectDebugInfo*
798a978a17SVictor Perevertkin FxVerifierGetObjectDebugInfo(
808a978a17SVictor Perevertkin     __in HANDLE Key,
818a978a17SVictor Perevertkin     __in PFX_DRIVER_GLOBALS  FxDriverGlobals
828a978a17SVictor Perevertkin     );
838a978a17SVictor Perevertkin 
848a978a17SVictor Perevertkin VOID
858a978a17SVictor Perevertkin FxVerifierQueryTrackPower(
868a978a17SVictor Perevertkin     __in HANDLE Key,
878a978a17SVictor Perevertkin     __out FxTrackPowerOption* TrackPower
888a978a17SVictor Perevertkin     );
898a978a17SVictor Perevertkin 
908a978a17SVictor Perevertkin //
918a978a17SVictor Perevertkin // Global allocation tracker
928a978a17SVictor Perevertkin //
938a978a17SVictor Perevertkin FX_POOL FxPoolFrameworks;
948a978a17SVictor Perevertkin 
958a978a17SVictor Perevertkin FxLibraryGlobalsType FxLibraryGlobals = { 0 };
968a978a17SVictor Perevertkin 
978a978a17SVictor Perevertkin //
988a978a17SVictor Perevertkin // These are defined in FxObjectInfo.cpp to account for the facts that
998a978a17SVictor Perevertkin //     1. FxObjectInfo array is different for UMDF and KMDF,
1008a978a17SVictor Perevertkin //     2. and not all the types are available in the common code
1018a978a17SVictor Perevertkin //
1028a978a17SVictor Perevertkin extern const FX_OBJECT_INFO FxObjectsInfo[];
1038a978a17SVictor Perevertkin extern ULONG FxObjectsInfoCount;
1048a978a17SVictor Perevertkin 
1058a978a17SVictor Perevertkin //
1068a978a17SVictor Perevertkin // Prevent compiler/linker/BBT from optimizing the global variable away
1078a978a17SVictor Perevertkin //
1088a978a17SVictor Perevertkin #if defined(_M_IX86)
1098a978a17SVictor Perevertkin #pragma comment(linker, "/include:_FxObjectsInfoCount")
1108a978a17SVictor Perevertkin #else
1118a978a17SVictor Perevertkin #pragma comment(linker, "/include:FxObjectsInfoCount")
1128a978a17SVictor Perevertkin #endif
1138a978a17SVictor Perevertkin 
1148a978a17SVictor Perevertkin 
1158a978a17SVictor Perevertkin _Must_inspect_result_
1168a978a17SVictor Perevertkin BOOLEAN
FxVerifyObjectTypeInTable(__in USHORT ObjectType)1178a978a17SVictor Perevertkin FxVerifyObjectTypeInTable(
1188a978a17SVictor Perevertkin     __in USHORT ObjectType
1198a978a17SVictor Perevertkin     )
1208a978a17SVictor Perevertkin {
1218a978a17SVictor Perevertkin     ULONG i;
1228a978a17SVictor Perevertkin 
1238a978a17SVictor Perevertkin     for (i = 0; i < FxObjectsInfoCount; i++) {
1248a978a17SVictor Perevertkin         if (ObjectType == FxObjectsInfo[i].ObjectType) {
1258a978a17SVictor Perevertkin             return TRUE;
1268a978a17SVictor Perevertkin         }
1278a978a17SVictor Perevertkin         else if (ObjectType > FxObjectsInfo[i].ObjectType) {
1288a978a17SVictor Perevertkin             continue;
1298a978a17SVictor Perevertkin         }
1308a978a17SVictor Perevertkin 
1318a978a17SVictor Perevertkin         return FALSE;
1328a978a17SVictor Perevertkin     }
1338a978a17SVictor Perevertkin 
1348a978a17SVictor Perevertkin     return FALSE;
1358a978a17SVictor Perevertkin }
1368a978a17SVictor Perevertkin 
1378a978a17SVictor Perevertkin _Must_inspect_result_
1388a978a17SVictor Perevertkin FxObjectDebugInfo*
FxVerifyAllocateDebugInfo(__in LPWSTR HandleNameList,__in PFX_DRIVER_GLOBALS FxDriverGlobals)1398a978a17SVictor Perevertkin FxVerifyAllocateDebugInfo(
1408a978a17SVictor Perevertkin     __in LPWSTR HandleNameList,
1418a978a17SVictor Perevertkin     __in PFX_DRIVER_GLOBALS FxDriverGlobals
1428a978a17SVictor Perevertkin     )
1438a978a17SVictor Perevertkin 
1448a978a17SVictor Perevertkin /*++
1458a978a17SVictor Perevertkin 
1468a978a17SVictor Perevertkin Routine Description:
1478a978a17SVictor Perevertkin     Allocates an array of FxObjectDebugInfo's.  The length of this array is the
1488a978a17SVictor Perevertkin     same length as FxObjectsInfo.  The array is sorted the same as
1498a978a17SVictor Perevertkin     FxObjectDebugInfo, ObjectInfo is ascending in the list.
1508a978a17SVictor Perevertkin 
1518a978a17SVictor Perevertkin     If HandleNameList's first string is "*", we treat this as a wildcard and
1528a978a17SVictor Perevertkin     track all external handles.
1538a978a17SVictor Perevertkin 
1548a978a17SVictor Perevertkin Arguments:
1558a978a17SVictor Perevertkin     HandleNameList - a multi-sz of handle names.  It is assumed the multi sz is
1568a978a17SVictor Perevertkin         well formed.
1578a978a17SVictor Perevertkin 
1588a978a17SVictor Perevertkin Return Value:
1598a978a17SVictor Perevertkin     a pointer allocated by ExAllocatePoolWithTag.  The caller is responsible for
1608a978a17SVictor Perevertkin     eventually freeing the pointer by calling ExFreePool.
1618a978a17SVictor Perevertkin 
1628a978a17SVictor Perevertkin --*/
1638a978a17SVictor Perevertkin 
1648a978a17SVictor Perevertkin {
1658a978a17SVictor Perevertkin     FxObjectDebugInfo* pInfo;
1668a978a17SVictor Perevertkin     PWCHAR pCur;
1678a978a17SVictor Perevertkin     ULONG i, length;
1688a978a17SVictor Perevertkin     BOOLEAN all;
1698a978a17SVictor Perevertkin 
1708a978a17SVictor Perevertkin     //
1718a978a17SVictor Perevertkin     // check to see if the multi sz is empty
1728a978a17SVictor Perevertkin     //
1738a978a17SVictor Perevertkin     if (*HandleNameList == NULL) {
1748a978a17SVictor Perevertkin         return NULL;
1758a978a17SVictor Perevertkin     }
1768a978a17SVictor Perevertkin 
1778a978a17SVictor Perevertkin     length = sizeof(FxObjectDebugInfo) * FxObjectsInfoCount;
1788a978a17SVictor Perevertkin 
1798a978a17SVictor Perevertkin     //
1808a978a17SVictor Perevertkin     // Freed with ExFreePool in FxFreeDriverGlobals.  Must be non paged because
1818a978a17SVictor Perevertkin     // objects can be allocated at IRQL > PASSIVE_LEVEL.
1828a978a17SVictor Perevertkin     //
1838a978a17SVictor Perevertkin     pInfo = (FxObjectDebugInfo*) MxMemory::MxAllocatePoolWithTag(NonPagedPool,
1848a978a17SVictor Perevertkin                                                        length,
1858a978a17SVictor Perevertkin                                                        FxDriverGlobals->Tag);
1868a978a17SVictor Perevertkin 
1878a978a17SVictor Perevertkin     if (pInfo == NULL) {
1888a978a17SVictor Perevertkin         return NULL;
1898a978a17SVictor Perevertkin     }
1908a978a17SVictor Perevertkin 
1918a978a17SVictor Perevertkin     all = *HandleNameList == L'*' ? TRUE : FALSE;
1928a978a17SVictor Perevertkin 
1938a978a17SVictor Perevertkin     RtlZeroMemory(pInfo, length);
1948a978a17SVictor Perevertkin 
1958a978a17SVictor Perevertkin     //
1968a978a17SVictor Perevertkin     // Iterate over all of the objects in our internal array.  We iterate over
1978a978a17SVictor Perevertkin     // this array instead of the multi sz list b/c this way we only convert
1988a978a17SVictor Perevertkin     // each ANSI string to UNICODE once.
1998a978a17SVictor Perevertkin     //
2008a978a17SVictor Perevertkin     for (i = 0; i < FxObjectsInfoCount; i++) {
2018a978a17SVictor Perevertkin         UNICODE_STRING objectName;
2028a978a17SVictor Perevertkin         WCHAR ubuffer[40];
2038a978a17SVictor Perevertkin         STRING string;
2048a978a17SVictor Perevertkin 
2058a978a17SVictor Perevertkin         pInfo[i].ObjectType = FxObjectsInfo[i].ObjectType;
2068a978a17SVictor Perevertkin 
2078a978a17SVictor Perevertkin         //
2088a978a17SVictor Perevertkin         // If this is an internal object, just continue past it
2098a978a17SVictor Perevertkin         //
2108a978a17SVictor Perevertkin         if (FxObjectsInfo[i].HandleName == NULL) {
2118a978a17SVictor Perevertkin             continue;
2128a978a17SVictor Perevertkin         }
2138a978a17SVictor Perevertkin 
2148a978a17SVictor Perevertkin         //
2158a978a17SVictor Perevertkin         // Short circuit if we are wildcarding
2168a978a17SVictor Perevertkin         //
2178a978a17SVictor Perevertkin         if (all) {
2188a978a17SVictor Perevertkin             pInfo[i].u.DebugFlags |= FxObjectDebugTrackReferences;
2198a978a17SVictor Perevertkin             continue;
2208a978a17SVictor Perevertkin         }
2218a978a17SVictor Perevertkin 
2228a978a17SVictor Perevertkin         RtlInitAnsiString(&string, FxObjectsInfo[i].HandleName);
2238a978a17SVictor Perevertkin 
2248a978a17SVictor Perevertkin         RtlZeroMemory(ubuffer, sizeof(ubuffer));
2258a978a17SVictor Perevertkin         objectName.Buffer = ubuffer;
2268a978a17SVictor Perevertkin         objectName.Length = 0;
2278a978a17SVictor Perevertkin         objectName.MaximumLength = sizeof(ubuffer);
2288a978a17SVictor Perevertkin 
2298a978a17SVictor Perevertkin         //
2308a978a17SVictor Perevertkin         // Conversion failed, just continue.  Failure is not critical to
2318a978a17SVictor Perevertkin         // returning the list.
2328a978a17SVictor Perevertkin         //
2338a978a17SVictor Perevertkin         if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&objectName,
2348a978a17SVictor Perevertkin                                                      &string,
2358a978a17SVictor Perevertkin                                                      FALSE))) {
2368a978a17SVictor Perevertkin             continue;
2378a978a17SVictor Perevertkin         }
2388a978a17SVictor Perevertkin 
2398a978a17SVictor Perevertkin         //
2408a978a17SVictor Perevertkin         // Now iterate over the multi sz list, comparing handle strings in the
2418a978a17SVictor Perevertkin         // list against the current object name.
2428a978a17SVictor Perevertkin         //
2438a978a17SVictor Perevertkin         pCur = HandleNameList;
2448a978a17SVictor Perevertkin 
2458a978a17SVictor Perevertkin         while (*pCur != UNICODE_NULL) {
2468a978a17SVictor Perevertkin             UNICODE_STRING handleName;
2478a978a17SVictor Perevertkin 
2488a978a17SVictor Perevertkin             RtlInitUnicodeString(&handleName, pCur);
2498a978a17SVictor Perevertkin 
2508a978a17SVictor Perevertkin             //
2518a978a17SVictor Perevertkin             // Increment to the next string now.  Add one so that we skip past
2528a978a17SVictor Perevertkin             // terminating null for this sz as well.
2538a978a17SVictor Perevertkin             // Length is the number of bytes, not the number of characters.
2548a978a17SVictor Perevertkin             //
2558a978a17SVictor Perevertkin             pCur += handleName.Length / sizeof(WCHAR) + 1;
2568a978a17SVictor Perevertkin 
2578a978a17SVictor Perevertkin             //
2588a978a17SVictor Perevertkin             // Case insensitive compare
2598a978a17SVictor Perevertkin             //
2608a978a17SVictor Perevertkin             if (RtlCompareUnicodeString(&handleName, &objectName, TRUE) == 0) {
2618a978a17SVictor Perevertkin                 pInfo[i].u.DebugFlags |= FxObjectDebugTrackReferences;
2628a978a17SVictor Perevertkin                 break;
2638a978a17SVictor Perevertkin             }
2648a978a17SVictor Perevertkin         }
2658a978a17SVictor Perevertkin     }
2668a978a17SVictor Perevertkin 
2678a978a17SVictor Perevertkin     return pInfo;
2688a978a17SVictor Perevertkin }
2698a978a17SVictor Perevertkin 
2708a978a17SVictor Perevertkin VOID
FxDriverGlobalsInitializeDebugExtension(__inout PFX_DRIVER_GLOBALS FxDriverGlobals,__in_opt HANDLE Key)2718a978a17SVictor Perevertkin FxDriverGlobalsInitializeDebugExtension(
2728a978a17SVictor Perevertkin     __inout PFX_DRIVER_GLOBALS FxDriverGlobals,
2738a978a17SVictor Perevertkin     __in_opt    HANDLE Key
2748a978a17SVictor Perevertkin     )
2758a978a17SVictor Perevertkin {
2768a978a17SVictor Perevertkin     FxDriverGlobalsDebugExtension* pExtension;
2778a978a17SVictor Perevertkin 
2788a978a17SVictor Perevertkin     //
2798a978a17SVictor Perevertkin     // The wdf subkey may not be present for inbox drivers that do not use inf.
2808a978a17SVictor Perevertkin     // Since Mdl tracking doen't need regsitry info we go ahead and allocate
2818a978a17SVictor Perevertkin     // debug extension for use in Mdl tracking. Tag tracker depends on registry
2828a978a17SVictor Perevertkin     // info and it won't be available if registry info is not present.
2838a978a17SVictor Perevertkin     //
2848a978a17SVictor Perevertkin 
2858a978a17SVictor Perevertkin     pExtension = (FxDriverGlobalsDebugExtension*) MxMemory::MxAllocatePoolWithTag(
2868a978a17SVictor Perevertkin         NonPagedPool, sizeof(FxDriverGlobalsDebugExtension), FxDriverGlobals->Tag);
2878a978a17SVictor Perevertkin 
2888a978a17SVictor Perevertkin     if (pExtension == NULL) {
2898a978a17SVictor Perevertkin         return;
2908a978a17SVictor Perevertkin     }
2918a978a17SVictor Perevertkin 
292*1f377076SVictor Perevertkin     *pExtension = {};
2938a978a17SVictor Perevertkin 
2948a978a17SVictor Perevertkin     pExtension->AllocatedTagTrackersLock.Initialize();
2958a978a17SVictor Perevertkin 
2968a978a17SVictor Perevertkin     InitializeListHead(&pExtension->AllocatedTagTrackersListHead);
2978a978a17SVictor Perevertkin 
2988a978a17SVictor Perevertkin     pExtension->TrackPower = FxTrackPowerNone;
2998a978a17SVictor Perevertkin 
3008a978a17SVictor Perevertkin     FxDriverGlobals->DebugExtension = pExtension;
3018a978a17SVictor Perevertkin 
3028a978a17SVictor Perevertkin     if (Key != NULL) {
3038a978a17SVictor Perevertkin         pExtension->ObjectDebugInfo = FxVerifierGetObjectDebugInfo(
3048a978a17SVictor Perevertkin                                                         Key,
3058a978a17SVictor Perevertkin                                                         FxDriverGlobals
3068a978a17SVictor Perevertkin                                                         );
3078a978a17SVictor Perevertkin         FxVerifierQueryTrackPower(Key, &pExtension->TrackPower);
3088a978a17SVictor Perevertkin     }
3098a978a17SVictor Perevertkin 
3108a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
3118a978a17SVictor Perevertkin     KeInitializeSpinLock(&pExtension->AllocatedMdlsLock);
3128a978a17SVictor Perevertkin #endif
3138a978a17SVictor Perevertkin }
3148a978a17SVictor Perevertkin 
3158a978a17SVictor Perevertkin PCSTR
FxObjectTypeToHandleName(__in WDFTYPE ObjectType)3168a978a17SVictor Perevertkin FxObjectTypeToHandleName(
3178a978a17SVictor Perevertkin     __in WDFTYPE ObjectType
3188a978a17SVictor Perevertkin     )
3198a978a17SVictor Perevertkin {
3208a978a17SVictor Perevertkin     ULONG i;
3218a978a17SVictor Perevertkin 
3228a978a17SVictor Perevertkin     for (i = 0; i < FxObjectsInfoCount; i++) {
3238a978a17SVictor Perevertkin         if (ObjectType == FxObjectsInfo[i].ObjectType) {
3248a978a17SVictor Perevertkin             return FxObjectsInfo[i].HandleName;
3258a978a17SVictor Perevertkin         }
3268a978a17SVictor Perevertkin         else if (ObjectType > FxObjectsInfo[i].ObjectType) {
3278a978a17SVictor Perevertkin             continue;
3288a978a17SVictor Perevertkin         }
3298a978a17SVictor Perevertkin 
3308a978a17SVictor Perevertkin         return NULL;
3318a978a17SVictor Perevertkin     }
3328a978a17SVictor Perevertkin 
3338a978a17SVictor Perevertkin     return NULL;
3348a978a17SVictor Perevertkin }
3358a978a17SVictor Perevertkin 
3368a978a17SVictor Perevertkin _Must_inspect_result_
3378a978a17SVictor Perevertkin BOOLEAN
FxVerifierGetTrackReferences(__in FxObjectDebugInfo * DebugInfo,__in WDFTYPE ObjectType)3388a978a17SVictor Perevertkin FxVerifierGetTrackReferences(
3398a978a17SVictor Perevertkin     __in FxObjectDebugInfo* DebugInfo,
3408a978a17SVictor Perevertkin     __in WDFTYPE ObjectType
3418a978a17SVictor Perevertkin     )
3428a978a17SVictor Perevertkin 
3438a978a17SVictor Perevertkin /*++
3448a978a17SVictor Perevertkin 
3458a978a17SVictor Perevertkin Routine Description:
3468a978a17SVictor Perevertkin     For a given object type, returns to the caller if it should track references
3478a978a17SVictor Perevertkin     to the object.
3488a978a17SVictor Perevertkin 
3498a978a17SVictor Perevertkin Arguments:
3508a978a17SVictor Perevertkin     DebugInfo - array of object debug info to search through
3518a978a17SVictor Perevertkin     ObjectType - the type of the object to check
3528a978a17SVictor Perevertkin 
3538a978a17SVictor Perevertkin Return Value:
3548a978a17SVictor Perevertkin     TRUE if references should be tracked, FALSE otherwise
3558a978a17SVictor Perevertkin 
3568a978a17SVictor Perevertkin --*/
3578a978a17SVictor Perevertkin 
3588a978a17SVictor Perevertkin {
3598a978a17SVictor Perevertkin     ULONG i;
3608a978a17SVictor Perevertkin 
3618a978a17SVictor Perevertkin     //
3628a978a17SVictor Perevertkin     // Array size of DebugInfo is the same size as FxObjectsInfo
3638a978a17SVictor Perevertkin     //
3648a978a17SVictor Perevertkin     for (i = 0; i < FxObjectsInfoCount; i++) {
3658a978a17SVictor Perevertkin         if (ObjectType == DebugInfo[i].ObjectType) {
3668a978a17SVictor Perevertkin             return FLAG_TO_BOOL(DebugInfo[i].u.DebugFlags,
3678a978a17SVictor Perevertkin                                 FxObjectDebugTrackReferences);
3688a978a17SVictor Perevertkin         }
3698a978a17SVictor Perevertkin         else if (ObjectType > FxObjectsInfo[i].ObjectType) {
3708a978a17SVictor Perevertkin             continue;
3718a978a17SVictor Perevertkin         }
3728a978a17SVictor Perevertkin 
3738a978a17SVictor Perevertkin         return FALSE;
3748a978a17SVictor Perevertkin     }
3758a978a17SVictor Perevertkin 
3768a978a17SVictor Perevertkin     return FALSE;
3778a978a17SVictor Perevertkin }
3788a978a17SVictor Perevertkin 
3798a978a17SVictor Perevertkin 
3808a978a17SVictor Perevertkin VOID
FxVerifyObjectTableIsSorted(VOID)3818a978a17SVictor Perevertkin FxVerifyObjectTableIsSorted(
3828a978a17SVictor Perevertkin     VOID
3838a978a17SVictor Perevertkin     )
3848a978a17SVictor Perevertkin {
3858a978a17SVictor Perevertkin     ULONG i;
3868a978a17SVictor Perevertkin     USHORT prevType;
3878a978a17SVictor Perevertkin 
3888a978a17SVictor Perevertkin     prevType = FxObjectsInfo[0].ObjectType;
3898a978a17SVictor Perevertkin 
3908a978a17SVictor Perevertkin     for (i = 1; i < FxObjectsInfoCount; i++) {
3918a978a17SVictor Perevertkin         if (prevType >= FxObjectsInfo[i].ObjectType) {
3928a978a17SVictor Perevertkin             ASSERTMSG("FxObjectsInfo table is not in sorted order\n",
3938a978a17SVictor Perevertkin                          prevType < FxObjectsInfo[i].ObjectType);
3948a978a17SVictor Perevertkin         }
3958a978a17SVictor Perevertkin 
3968a978a17SVictor Perevertkin         prevType = FxObjectsInfo[i].ObjectType;
3978a978a17SVictor Perevertkin     }
3988a978a17SVictor Perevertkin }
3998a978a17SVictor Perevertkin 
4008a978a17SVictor Perevertkin typedef
4018a978a17SVictor Perevertkin NTSTATUS
4028a978a17SVictor Perevertkin (*PFN_RTL_GET_VERSION)(
4038a978a17SVictor Perevertkin     __out PRTL_OSVERSIONINFOW VersionInformation
4048a978a17SVictor Perevertkin     );
4058a978a17SVictor Perevertkin 
4068a978a17SVictor Perevertkin typedef
4078a978a17SVictor Perevertkin NTSTATUS
4088a978a17SVictor Perevertkin (*PFN_RTL_VERIFY_VERSION_INFO)(
4098a978a17SVictor Perevertkin     __in PRTL_OSVERSIONINFOEXW VersionInfo,
4108a978a17SVictor Perevertkin     __in ULONG TypeMask,
4118a978a17SVictor Perevertkin     __in ULONGLONG  ConditionMask
4128a978a17SVictor Perevertkin     );
4138a978a17SVictor Perevertkin 
4148a978a17SVictor Perevertkin typedef
4158a978a17SVictor Perevertkin ULONGLONG
4168a978a17SVictor Perevertkin (*PFN_VER_SET_CONDITION_MASK)(
4178a978a17SVictor Perevertkin     __in  ULONGLONG   ConditionMask,
4188a978a17SVictor Perevertkin     __in  ULONG   TypeMask,
4198a978a17SVictor Perevertkin     __in  UCHAR   Condition
4208a978a17SVictor Perevertkin     );
4218a978a17SVictor Perevertkin 
4228a978a17SVictor Perevertkin VOID
FxLibraryGlobalsVerifyVersion(VOID)4238a978a17SVictor Perevertkin FxLibraryGlobalsVerifyVersion(
4248a978a17SVictor Perevertkin     VOID
4258a978a17SVictor Perevertkin     )
4268a978a17SVictor Perevertkin {
4278a978a17SVictor Perevertkin     RTL_OSVERSIONINFOEXW info;
4288a978a17SVictor Perevertkin     PFN_RTL_VERIFY_VERSION_INFO pRtlVerifyVersionInfo;
4298a978a17SVictor Perevertkin     PFN_VER_SET_CONDITION_MASK pVerSetConditionMask;
4308a978a17SVictor Perevertkin     ULONGLONG condition;
4318a978a17SVictor Perevertkin     NTSTATUS status;
4328a978a17SVictor Perevertkin 
4338a978a17SVictor Perevertkin     pRtlVerifyVersionInfo = (PFN_RTL_VERIFY_VERSION_INFO)
4348a978a17SVictor Perevertkin         Mx::MxGetSystemRoutineAddress(MAKE_MX_FUNC_NAME("RtlVerifyVersionInfo"));
4358a978a17SVictor Perevertkin 
4368a978a17SVictor Perevertkin     if (pRtlVerifyVersionInfo == NULL) {
4378a978a17SVictor Perevertkin         return;
4388a978a17SVictor Perevertkin     }
4398a978a17SVictor Perevertkin 
4408a978a17SVictor Perevertkin     pVerSetConditionMask = (PFN_VER_SET_CONDITION_MASK)
4418a978a17SVictor Perevertkin         Mx::MxGetSystemRoutineAddress(MAKE_MX_FUNC_NAME("VerSetConditionMask"));
4428a978a17SVictor Perevertkin 
4438a978a17SVictor Perevertkin     //
4448a978a17SVictor Perevertkin     // Check for Win8 (6.2) and later for passive-level interrupt support.
4458a978a17SVictor Perevertkin     //
4468a978a17SVictor Perevertkin     RtlZeroMemory(&info, sizeof(info));
4478a978a17SVictor Perevertkin     info.dwOSVersionInfoSize = sizeof(info);
4488a978a17SVictor Perevertkin     info.dwMajorVersion = 6;
4498a978a17SVictor Perevertkin     info.dwMinorVersion = 2;
4508a978a17SVictor Perevertkin 
4518a978a17SVictor Perevertkin     condition = 0;
4528a978a17SVictor Perevertkin     condition = pVerSetConditionMask(condition, VER_MAJORVERSION, VER_GREATER_EQUAL);
4538a978a17SVictor Perevertkin     condition = pVerSetConditionMask(condition, VER_MINORVERSION, VER_GREATER_EQUAL);
4548a978a17SVictor Perevertkin 
4558a978a17SVictor Perevertkin     status = pRtlVerifyVersionInfo(&info,
4568a978a17SVictor Perevertkin                                    VER_MAJORVERSION | VER_MINORVERSION,
4578a978a17SVictor Perevertkin                                    condition);
4588a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
4598a978a17SVictor Perevertkin         FxLibraryGlobals.PassiveLevelInterruptSupport = TRUE;
4608a978a17SVictor Perevertkin     }
4618a978a17SVictor Perevertkin }
4628a978a17SVictor Perevertkin 
4638a978a17SVictor Perevertkin VOID
FxLibraryGlobalsQueryRegistrySettings(VOID)4648a978a17SVictor Perevertkin FxLibraryGlobalsQueryRegistrySettings(
4658a978a17SVictor Perevertkin     VOID
4668a978a17SVictor Perevertkin     )
4678a978a17SVictor Perevertkin {
4688a978a17SVictor Perevertkin     FxAutoRegKey hWdf;
4698a978a17SVictor Perevertkin     NTSTATUS status = STATUS_SUCCESS;
4708a978a17SVictor Perevertkin     DECLARE_CONST_UNICODE_STRING(path, WDF_REGISTRY_BASE_PATH);
4718a978a17SVictor Perevertkin     DECLARE_CONST_UNICODE_STRING(ifrDisabledName, WDF_GLOBAL_VALUE_IFRDISABLED);
4728a978a17SVictor Perevertkin     ULONG ifrDisabled = 0;
4738a978a17SVictor Perevertkin 
4748a978a17SVictor Perevertkin     status = FxRegKey::_OpenKey(NULL, &path, &hWdf.m_Key, KEY_READ);
4758a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
4768a978a17SVictor Perevertkin         goto exit;
4778a978a17SVictor Perevertkin     }
4788a978a17SVictor Perevertkin 
4798a978a17SVictor Perevertkin     status = FxRegKey::_QueryULong(hWdf.m_Key, &ifrDisabledName, &ifrDisabled);
4808a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
4818a978a17SVictor Perevertkin         goto exit;
4828a978a17SVictor Perevertkin     }
4838a978a17SVictor Perevertkin 
4848a978a17SVictor Perevertkin     if (ifrDisabled == 1) {
4858a978a17SVictor Perevertkin         FxLibraryGlobals.IfrDisabled = TRUE;
4868a978a17SVictor Perevertkin     }
4878a978a17SVictor Perevertkin 
4888a978a17SVictor Perevertkin exit:
4898a978a17SVictor Perevertkin     return;
4908a978a17SVictor Perevertkin }
4918a978a17SVictor Perevertkin 
4928a978a17SVictor Perevertkin _Must_inspect_result_
4938a978a17SVictor Perevertkin NTSTATUS
FxLibraryGlobalsCommission(VOID)4948a978a17SVictor Perevertkin FxLibraryGlobalsCommission(
4958a978a17SVictor Perevertkin     VOID
4968a978a17SVictor Perevertkin     )
4978a978a17SVictor Perevertkin {
4988a978a17SVictor Perevertkin     PFN_RTL_GET_VERSION pRtlGetVersion;
4998a978a17SVictor Perevertkin     NTSTATUS status;
5008a978a17SVictor Perevertkin 
5018a978a17SVictor Perevertkin     //
5028a978a17SVictor Perevertkin     // Global initialization for mode-agnostic primitives library
5038a978a17SVictor Perevertkin     //
5048a978a17SVictor Perevertkin     Mx::MxGlobalInit();
5058a978a17SVictor Perevertkin 
5068a978a17SVictor Perevertkin 
5078a978a17SVictor Perevertkin 
5088a978a17SVictor Perevertkin 
5098a978a17SVictor Perevertkin 
5108a978a17SVictor Perevertkin 
5118a978a17SVictor Perevertkin 
5128a978a17SVictor Perevertkin 
5138a978a17SVictor Perevertkin 
5148a978a17SVictor Perevertkin 
5158a978a17SVictor Perevertkin 
5168a978a17SVictor Perevertkin 
5178a978a17SVictor Perevertkin 
5188a978a17SVictor Perevertkin 
5198a978a17SVictor Perevertkin 
5208a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
5218a978a17SVictor Perevertkin     FxLibraryGlobals.IsUserModeFramework = FALSE;
5228a978a17SVictor Perevertkin #else
5238a978a17SVictor Perevertkin     FxLibraryGlobals.IsUserModeFramework = TRUE;
5248a978a17SVictor Perevertkin #endif
5258a978a17SVictor Perevertkin 
5268a978a17SVictor Perevertkin     //
5278a978a17SVictor Perevertkin     // IFR is enabled by default
5288a978a17SVictor Perevertkin     //
5298a978a17SVictor Perevertkin     FxLibraryGlobals.IfrDisabled = FALSE;
5308a978a17SVictor Perevertkin 
5318a978a17SVictor Perevertkin     //
5328a978a17SVictor Perevertkin     // Query global WDF settings (both KMDF and UMDF).
5338a978a17SVictor Perevertkin     //
5348a978a17SVictor Perevertkin     FxLibraryGlobalsQueryRegistrySettings();
5358a978a17SVictor Perevertkin 
5368a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
5378a978a17SVictor Perevertkin     UNICODE_STRING funcName;
5388a978a17SVictor Perevertkin 
5398a978a17SVictor Perevertkin     // For DSF support.
5408a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"IoConnectInterruptEx");
5418a978a17SVictor Perevertkin     FxLibraryGlobals.IoConnectInterruptEx = (PFN_IO_CONNECT_INTERRUPT_EX)
5428a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5438a978a17SVictor Perevertkin 
5448a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"IoDisconnectInterruptEx");
5458a978a17SVictor Perevertkin     FxLibraryGlobals.IoDisconnectInterruptEx = (PFN_IO_DISCONNECT_INTERRUPT_EX)
5468a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5478a978a17SVictor Perevertkin 
5488a978a17SVictor Perevertkin     // 32 bit: W2k and forward.
5498a978a17SVictor Perevertkin     // 64 bit: W2k -> Windows Server 2008 (obsolete otherwise).
5508a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"KeQueryActiveProcessors");
5518a978a17SVictor Perevertkin     FxLibraryGlobals.KeQueryActiveProcessors = (PFN_KE_QUERY_ACTIVE_PROCESSORS)
5528a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5538a978a17SVictor Perevertkin 
5548a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"KeSetTargetProcessorDpc");
5558a978a17SVictor Perevertkin     FxLibraryGlobals.KeSetTargetProcessorDpc = (PFN_KE_SET_TARGET_PROCESSOR_DPC)
5568a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5578a978a17SVictor Perevertkin 
5588a978a17SVictor Perevertkin     // These should always be there (obsolete in 64 bit Win 7 and forward).
5598a978a17SVictor Perevertkin     ASSERT(FxLibraryGlobals.KeQueryActiveProcessors != NULL &&
5608a978a17SVictor Perevertkin            FxLibraryGlobals.KeSetTargetProcessorDpc != NULL);
5618a978a17SVictor Perevertkin 
5628a978a17SVictor Perevertkin     // Win 7 and forward.
5638a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"KeQueryActiveGroupCount");
5648a978a17SVictor Perevertkin     if (MmGetSystemRoutineAddress(&funcName) != NULL) {
5658a978a17SVictor Perevertkin         FxLibraryGlobals.ProcessorGroupSupport = TRUE;
5668a978a17SVictor Perevertkin     }
5678a978a17SVictor Perevertkin 
5688a978a17SVictor Perevertkin     // Win 7 and forward.
5698a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"KeSetCoalescableTimer");
5708a978a17SVictor Perevertkin     FxLibraryGlobals.KeSetCoalescableTimer = (PFN_KE_SET_COALESCABLE_TIMER)
5718a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5728a978a17SVictor Perevertkin 
5738a978a17SVictor Perevertkin     // Win 7 and forward.
5748a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"IoUnregisterPlugPlayNotificationEx");
5758a978a17SVictor Perevertkin     FxLibraryGlobals.IoUnregisterPlugPlayNotificationEx = (PFN_IO_UNREGISTER_PLUGPLAY_NOTIFICATION_EX)
5768a978a17SVictor Perevertkin         MmGetSystemRoutineAddress(&funcName);
5778a978a17SVictor Perevertkin 
5788a978a17SVictor Perevertkin     // Win 8 and forward
5798a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxRegisterDevice");
5808a978a17SVictor Perevertkin     FxLibraryGlobals.PoxRegisterDevice =
5818a978a17SVictor Perevertkin       (PFN_POX_REGISTER_DEVICE) MmGetSystemRoutineAddress(&funcName);
5828a978a17SVictor Perevertkin 
5838a978a17SVictor Perevertkin     // Win 8 and forward
5848a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxStartDevicePowerManagement");
5858a978a17SVictor Perevertkin     FxLibraryGlobals.PoxStartDevicePowerManagement =
5868a978a17SVictor Perevertkin                                     (PFN_POX_START_DEVICE_POWER_MANAGEMENT)
5878a978a17SVictor Perevertkin                                         MmGetSystemRoutineAddress(&funcName);
5888a978a17SVictor Perevertkin 
5898a978a17SVictor Perevertkin     // Win 8 and forward
5908a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxUnregisterDevice");
5918a978a17SVictor Perevertkin     FxLibraryGlobals.PoxUnregisterDevice =
5928a978a17SVictor Perevertkin                                 (PFN_POX_UNREGISTER_DEVICE)
5938a978a17SVictor Perevertkin                                     MmGetSystemRoutineAddress(&funcName);
5948a978a17SVictor Perevertkin 
5958a978a17SVictor Perevertkin     // Win 8 and forward
5968a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxActivateComponent");
5978a978a17SVictor Perevertkin     FxLibraryGlobals.PoxActivateComponent = (PFN_POX_ACTIVATE_COMPONENT)
5988a978a17SVictor Perevertkin                                           MmGetSystemRoutineAddress(&funcName);
5998a978a17SVictor Perevertkin 
6008a978a17SVictor Perevertkin     // Win 8 and forward
6018a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxIdleComponent");
6028a978a17SVictor Perevertkin     FxLibraryGlobals.PoxIdleComponent = (PFN_POX_IDLE_COMPONENT)
6038a978a17SVictor Perevertkin                                           MmGetSystemRoutineAddress(&funcName);
6048a978a17SVictor Perevertkin 
6058a978a17SVictor Perevertkin     // Win 8 and forward
6068a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxReportDevicePoweredOn");
6078a978a17SVictor Perevertkin     FxLibraryGlobals.PoxReportDevicePoweredOn =
6088a978a17SVictor Perevertkin       (PFN_POX_REPORT_DEVICE_POWERED_ON) MmGetSystemRoutineAddress(&funcName);
6098a978a17SVictor Perevertkin 
6108a978a17SVictor Perevertkin     // Win 8 and forward
6118a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxCompleteIdleState");
6128a978a17SVictor Perevertkin     FxLibraryGlobals.PoxCompleteIdleState =
6138a978a17SVictor Perevertkin       (PFN_POX_COMPLETE_IDLE_STATE) MmGetSystemRoutineAddress(&funcName);
6148a978a17SVictor Perevertkin 
6158a978a17SVictor Perevertkin     // Win 8 and forward
6168a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxCompleteIdleCondition");
6178a978a17SVictor Perevertkin     FxLibraryGlobals.PoxCompleteIdleCondition =
6188a978a17SVictor Perevertkin       (PFN_POX_COMPLETE_IDLE_CONDITION) MmGetSystemRoutineAddress(&funcName);
6198a978a17SVictor Perevertkin 
6208a978a17SVictor Perevertkin     // Win 8 and forward
6218a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxCompleteDevicePowerNotRequired");
6228a978a17SVictor Perevertkin     FxLibraryGlobals.PoxCompleteDevicePowerNotRequired =
6238a978a17SVictor Perevertkin       (PFN_POX_COMPLETE_DEVICE_POWER_NOT_REQUIRED) MmGetSystemRoutineAddress(&funcName);
6248a978a17SVictor Perevertkin 
6258a978a17SVictor Perevertkin     // Win 8 and forward
6268a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"PoFxSetDeviceIdleTimeout");
6278a978a17SVictor Perevertkin     FxLibraryGlobals.PoxSetDeviceIdleTimeout =
6288a978a17SVictor Perevertkin       (PFN_POX_SET_DEVICE_IDLE_TIMEOUT) MmGetSystemRoutineAddress(&funcName);
6298a978a17SVictor Perevertkin 
6308a978a17SVictor Perevertkin     // Win 8 and forward
6318a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"IoReportInterruptActive");
6328a978a17SVictor Perevertkin     FxLibraryGlobals.IoReportInterruptActive =
6338a978a17SVictor Perevertkin       (PFN_IO_REPORT_INTERRUPT_ACTIVE) MmGetSystemRoutineAddress(&funcName);
6348a978a17SVictor Perevertkin 
6358a978a17SVictor Perevertkin     // Win 8 and forward
6368a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"IoReportInterruptInactive");
6378a978a17SVictor Perevertkin     FxLibraryGlobals.IoReportInterruptInactive =
6388a978a17SVictor Perevertkin       (PFN_IO_REPORT_INTERRUPT_INACTIVE) MmGetSystemRoutineAddress(&funcName);
6398a978a17SVictor Perevertkin 
6408a978a17SVictor Perevertkin     // Win 8.2 and forward
6418a978a17SVictor Perevertkin     RtlInitUnicodeString(&funcName, L"VfCheckNxPoolType");
6428a978a17SVictor Perevertkin     FxLibraryGlobals.VfCheckNxPoolType =
6438a978a17SVictor Perevertkin       (PFN_VF_CHECK_NX_POOL_TYPE) MmGetSystemRoutineAddress(&funcName);
6448a978a17SVictor Perevertkin 
6458a978a17SVictor Perevertkin #endif //((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
6468a978a17SVictor Perevertkin 
6478a978a17SVictor Perevertkin     FxLibraryGlobals.OsVersionInfo.dwOSVersionInfoSize = sizeof(FxLibraryGlobals.OsVersionInfo);
6488a978a17SVictor Perevertkin 
6498a978a17SVictor Perevertkin     // User/Kernel agnostic.
6508a978a17SVictor Perevertkin 
6518a978a17SVictor Perevertkin     pRtlGetVersion = (PFN_RTL_GET_VERSION)
6528a978a17SVictor Perevertkin                 Mx::MxGetSystemRoutineAddress(MAKE_MX_FUNC_NAME("RtlGetVersion"));
6538a978a17SVictor Perevertkin 
6548a978a17SVictor Perevertkin     ASSERT(pRtlGetVersion != NULL);
6558a978a17SVictor Perevertkin     pRtlGetVersion((PRTL_OSVERSIONINFOW) &FxLibraryGlobals.OsVersionInfo);
6568a978a17SVictor Perevertkin     FxLibraryGlobalsVerifyVersion();
6578a978a17SVictor Perevertkin 
6588a978a17SVictor Perevertkin     //
6598a978a17SVictor Perevertkin     // Initialize power management-related stuff.
6608a978a17SVictor Perevertkin     //
6618a978a17SVictor Perevertkin     RtlZeroMemory(&FxLibraryGlobals.MachineSleepStates[0],
6628a978a17SVictor Perevertkin                   sizeof(FxLibraryGlobals.MachineSleepStates));
6638a978a17SVictor Perevertkin 
6648a978a17SVictor Perevertkin     //
6658a978a17SVictor Perevertkin     // Insure that the FxObject is layed-up correctly.
6668a978a17SVictor Perevertkin     //
6678a978a17SVictor Perevertkin     FxVerifyObjectTableIsSorted();
6688a978a17SVictor Perevertkin 
6698a978a17SVictor Perevertkin     //
6708a978a17SVictor Perevertkin     // Initialize the list of FxDriverGlobals.
6718a978a17SVictor Perevertkin     // This is essentially the list of drivers on this WDF version.
6728a978a17SVictor Perevertkin     //
6738a978a17SVictor Perevertkin     InitializeListHead(&FxLibraryGlobals.FxDriverGlobalsList);
6748a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Initialize();
6758a978a17SVictor Perevertkin 
6768a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
6778a978a17SVictor Perevertkin     //
6788a978a17SVictor Perevertkin     // Register for the global (library) bugcheck callbacks.
6798a978a17SVictor Perevertkin     //
6808a978a17SVictor Perevertkin     FxInitializeBugCheckDriverInfo();
681*1f377076SVictor Perevertkin #ifdef EVENT_TRACING // __REACTOS__
6828a978a17SVictor Perevertkin     //
6838a978a17SVictor Perevertkin     // Init driver usage tracker. This tracker is used by the debug dump
6848a978a17SVictor Perevertkin     // callback routines for finding the driver's dump log file to write
6858a978a17SVictor Perevertkin     // in the minidump. Ignore any tracker's errors.
6868a978a17SVictor Perevertkin     //
6878a978a17SVictor Perevertkin     (VOID)FxLibraryGlobals.DriverTracker.Initialize();
6888a978a17SVictor Perevertkin 
6898a978a17SVictor Perevertkin     //
6908a978a17SVictor Perevertkin     // Initialize enhanced-verifier section handle
6918a978a17SVictor Perevertkin     //
6928a978a17SVictor Perevertkin     FxLibraryGlobals.VerifierSectionHandle = NULL;
6938a978a17SVictor Perevertkin     FxLibraryGlobals.VerifierSectionHandleRefCount = 0;
6948a978a17SVictor Perevertkin 
6958a978a17SVictor Perevertkin     //
6968a978a17SVictor Perevertkin     // Retrieve a pointer to the data structure that cotains trace routines
6978a978a17SVictor Perevertkin     // corresponding to WdfNotifyRoutinesClass from the SystemTraceProvider
6988a978a17SVictor Perevertkin     // that we'll use for perf tracing of WDF operations. The trace
6998a978a17SVictor Perevertkin     // routines inside the structuyre are present only when tracing is enabled
7008a978a17SVictor Perevertkin     // by some trace client (e.g. tracelog or xperf)  for WDF specific perf
7018a978a17SVictor Perevertkin     // groups. Note that no unregistration is necessary.
7028a978a17SVictor Perevertkin     //
7038a978a17SVictor Perevertkin     status = WmiQueryTraceInformation(WdfNotifyRoutinesClass,
7048a978a17SVictor Perevertkin                                       &FxLibraryGlobals.PerfTraceRoutines,
7058a978a17SVictor Perevertkin                                       sizeof(PWMI_WDF_NOTIFY_ROUTINES),
7068a978a17SVictor Perevertkin                                       NULL,
7078a978a17SVictor Perevertkin                                       NULL);
7088a978a17SVictor Perevertkin 
7098a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
7108a978a17SVictor Perevertkin         //
7118a978a17SVictor Perevertkin         // WDF trace routines are available only on win8+, so failure is
7128a978a17SVictor Perevertkin         // expected on pre-Win8 OS. Use the dummy routines on failure.
7138a978a17SVictor Perevertkin         //
7148a978a17SVictor Perevertkin         RtlZeroMemory(&FxLibraryGlobals.DummyPerfTraceRoutines,
7158a978a17SVictor Perevertkin                       sizeof(WMI_WDF_NOTIFY_ROUTINES));
7168a978a17SVictor Perevertkin         FxLibraryGlobals.DummyPerfTraceRoutines.Size =
7178a978a17SVictor Perevertkin             sizeof(WMI_WDF_NOTIFY_ROUTINES);
7188a978a17SVictor Perevertkin         FxLibraryGlobals.PerfTraceRoutines =
7198a978a17SVictor Perevertkin             &FxLibraryGlobals.DummyPerfTraceRoutines;
7208a978a17SVictor Perevertkin         status = STATUS_SUCCESS;
7218a978a17SVictor Perevertkin     }
7228a978a17SVictor Perevertkin 
7238a978a17SVictor Perevertkin     //
7248a978a17SVictor Perevertkin     // The Size member of WMI_WDF_NOTIFY_ROUTINES allows versioning. When
7258a978a17SVictor Perevertkin     // the WMI_WDF_NOTIFY_ROUTINES structure is revised with additional
7268a978a17SVictor Perevertkin     // members in future OS versions, the Size member will allow validating
7278a978a17SVictor Perevertkin     // the various versions, and initializeing the structure correctly.
7288a978a17SVictor Perevertkin     //
7298a978a17SVictor Perevertkin     ASSERT(FxLibraryGlobals.PerfTraceRoutines->Size >=
7308a978a17SVictor Perevertkin         sizeof(WMI_WDF_NOTIFY_ROUTINES));
731*1f377076SVictor Perevertkin #else
732*1f377076SVictor Perevertkin     status = STATUS_SUCCESS; // __REACTOS__
733*1f377076SVictor Perevertkin #endif // EVENT_TRACING
7348a978a17SVictor Perevertkin #else
7358a978a17SVictor Perevertkin     status = STATUS_SUCCESS;
7368a978a17SVictor Perevertkin #endif
7378a978a17SVictor Perevertkin 
7388a978a17SVictor Perevertkin     return status;
7398a978a17SVictor Perevertkin }
7408a978a17SVictor Perevertkin 
7418a978a17SVictor Perevertkin VOID
FxLibraryGlobalsDecommission(VOID)7428a978a17SVictor Perevertkin FxLibraryGlobalsDecommission(
7438a978a17SVictor Perevertkin     VOID
7448a978a17SVictor Perevertkin     )
7458a978a17SVictor Perevertkin {
7468a978a17SVictor Perevertkin     //
7478a978a17SVictor Perevertkin     // Assure the all driver's FxDriverGlobals have been freed.
7488a978a17SVictor Perevertkin     //
7498a978a17SVictor Perevertkin     ASSERT(IsListEmpty(&FxLibraryGlobals.FxDriverGlobalsList));
7508a978a17SVictor Perevertkin 
7518a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
7528a978a17SVictor Perevertkin     //
7538a978a17SVictor Perevertkin     // Cleanup for the driver usage tracker.
7548a978a17SVictor Perevertkin     //
7558a978a17SVictor Perevertkin     FxLibraryGlobals.DriverTracker.Uninitialize();
7568a978a17SVictor Perevertkin 
7578a978a17SVictor Perevertkin     //
7588a978a17SVictor Perevertkin     // Deregister from the global (library) bugcheck callbacks.
7598a978a17SVictor Perevertkin     //
7608a978a17SVictor Perevertkin     FxUninitializeBugCheckDriverInfo();
7618a978a17SVictor Perevertkin #endif
7628a978a17SVictor Perevertkin 
7638a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Uninitialize();
7648a978a17SVictor Perevertkin 
7658a978a17SVictor Perevertkin     return;
7668a978a17SVictor Perevertkin }
7678a978a17SVictor Perevertkin 
7688a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
7698a978a17SVictor Perevertkin //
7708a978a17SVictor Perevertkin // This function is only used to lock down verifier section code in memory.
7718a978a17SVictor Perevertkin // It uses the #pragma alloc_text(...) style for paging.
7728a978a17SVictor Perevertkin //
7738a978a17SVictor Perevertkin VOID
VerifierPageLockHandle(VOID)7748a978a17SVictor Perevertkin VerifierPageLockHandle (
7758a978a17SVictor Perevertkin     VOID
7768a978a17SVictor Perevertkin     )
7778a978a17SVictor Perevertkin {
7788a978a17SVictor Perevertkin     PAGED_CODE_LOCKED();
7798a978a17SVictor Perevertkin     DO_NOTHING();
7808a978a17SVictor Perevertkin }
7818a978a17SVictor Perevertkin 
7828a978a17SVictor Perevertkin VOID
LockVerifierSection(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals,_In_ PCUNICODE_STRING RegistryPath)7838a978a17SVictor Perevertkin LockVerifierSection(
7848a978a17SVictor Perevertkin     _In_ PFX_DRIVER_GLOBALS FxDriverGlobals,
7858a978a17SVictor Perevertkin     _In_ PCUNICODE_STRING RegistryPath
7868a978a17SVictor Perevertkin     )
7878a978a17SVictor Perevertkin {
7888a978a17SVictor Perevertkin     LONG count;
7898a978a17SVictor Perevertkin 
7908a978a17SVictor Perevertkin     //
7918a978a17SVictor Perevertkin     // This asserts  makes sure the struct is not pack(1) and the counter
7928a978a17SVictor Perevertkin     // is correctly aligned on a 32 bit boundary.
7938a978a17SVictor Perevertkin     //
7948a978a17SVictor Perevertkin     C_ASSERT((FIELD_OFFSET(FxLibraryGlobalsType, VerifierSectionHandleRefCount)
7958a978a17SVictor Perevertkin               % __alignof(LONG)) == 0);
7968a978a17SVictor Perevertkin 
7978a978a17SVictor Perevertkin     count = InterlockedIncrement(&FxLibraryGlobals.VerifierSectionHandleRefCount);
7988a978a17SVictor Perevertkin     ASSERT(count > 0);
7998a978a17SVictor Perevertkin 
8008a978a17SVictor Perevertkin     //
8018a978a17SVictor Perevertkin     // If verifier section is unlocked, lock it in.
8028a978a17SVictor Perevertkin     //
8038a978a17SVictor Perevertkin     if(FxLibraryGlobals.VerifierSectionHandle == NULL) {
8048a978a17SVictor Perevertkin         //
8058a978a17SVictor Perevertkin         //First time verifier section is being locked.
8068a978a17SVictor Perevertkin         //
8078a978a17SVictor Perevertkin         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
8088a978a17SVictor Perevertkin                             "First time Locking (%d) in Verifier Paged Memory "
8098a978a17SVictor Perevertkin                             "from  %!wZ! from driver globals %p",
8108a978a17SVictor Perevertkin                             count, RegistryPath, FxDriverGlobals);
8118a978a17SVictor Perevertkin         //
8128a978a17SVictor Perevertkin         // VerifierLockHandle is a function that we use to lock in all the code from it's section
8138a978a17SVictor Perevertkin         // since all the verifier code is in the same section as VerifierLockHandle.
8148a978a17SVictor Perevertkin         //
815*1f377076SVictor Perevertkin         FxLibraryGlobals.VerifierSectionHandle = MmLockPagableCodeSection((PVOID)VerifierPageLockHandle);
8168a978a17SVictor Perevertkin     }
8178a978a17SVictor Perevertkin     else {
8188a978a17SVictor Perevertkin         MmLockPagableSectionByHandle(FxLibraryGlobals.VerifierSectionHandle);
8198a978a17SVictor Perevertkin         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
8208a978a17SVictor Perevertkin                             "Increment Lock counter (%d) for Verifier Paged Memory "
8218a978a17SVictor Perevertkin                             "from  %!wZ! from driver globals %p",
8228a978a17SVictor Perevertkin                             count, RegistryPath, FxDriverGlobals);
8238a978a17SVictor Perevertkin     }
8248a978a17SVictor Perevertkin }
8258a978a17SVictor Perevertkin 
8268a978a17SVictor Perevertkin VOID
UnlockVerifierSection(_In_ PFX_DRIVER_GLOBALS FxDriverGlobals)8278a978a17SVictor Perevertkin UnlockVerifierSection(
8288a978a17SVictor Perevertkin     _In_ PFX_DRIVER_GLOBALS FxDriverGlobals
8298a978a17SVictor Perevertkin     )
8308a978a17SVictor Perevertkin {
8318a978a17SVictor Perevertkin     if( FxLibraryGlobals.VerifierSectionHandle != NULL) {
8328a978a17SVictor Perevertkin         LONG count;
8338a978a17SVictor Perevertkin 
8348a978a17SVictor Perevertkin         count = InterlockedDecrement(&FxLibraryGlobals.VerifierSectionHandleRefCount);
8358a978a17SVictor Perevertkin         ASSERT(count >= 0);
8368a978a17SVictor Perevertkin 
8378a978a17SVictor Perevertkin         MmUnlockPagableImageSection(FxLibraryGlobals.VerifierSectionHandle);
8388a978a17SVictor Perevertkin         DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGDRIVER,
8398a978a17SVictor Perevertkin                             "Decrement UnLock counter (%d) for Verifier Paged Memory "
8408a978a17SVictor Perevertkin                             "with driver globals %p",
8418a978a17SVictor Perevertkin                             count, FxDriverGlobals);
8428a978a17SVictor Perevertkin     }
8438a978a17SVictor Perevertkin }
8448a978a17SVictor Perevertkin #endif
8458a978a17SVictor Perevertkin 
8468a978a17SVictor Perevertkin _Must_inspect_result_
8478a978a17SVictor Perevertkin NTSTATUS
FxInitialize(__inout PFX_DRIVER_GLOBALS FxDriverGlobals,__in MdDriverObject DriverObject,__in PCUNICODE_STRING RegistryPath,__in_opt PWDF_DRIVER_CONFIG DriverConfig)8488a978a17SVictor Perevertkin FxInitialize(
8498a978a17SVictor Perevertkin     __inout     PFX_DRIVER_GLOBALS FxDriverGlobals,
8508a978a17SVictor Perevertkin     __in        MdDriverObject DriverObject,
8518a978a17SVictor Perevertkin     __in        PCUNICODE_STRING RegistryPath,
8528a978a17SVictor Perevertkin     __in_opt    PWDF_DRIVER_CONFIG DriverConfig
8538a978a17SVictor Perevertkin     )
8548a978a17SVictor Perevertkin 
8558a978a17SVictor Perevertkin /*++
8568a978a17SVictor Perevertkin 
8578a978a17SVictor Perevertkin Routine Description:
8588a978a17SVictor Perevertkin 
8598a978a17SVictor Perevertkin     This is the global framework initialization routine.
8608a978a17SVictor Perevertkin 
8618a978a17SVictor Perevertkin     This is called when the framework is loaded, and by
8628a978a17SVictor Perevertkin     any drivers that use the framework.
8638a978a17SVictor Perevertkin 
8648a978a17SVictor Perevertkin     It is safe to call if already initialized, to handle
8658a978a17SVictor Perevertkin     cases where multiple drivers are sharing a common
8668a978a17SVictor Perevertkin     kernel DLL.
8678a978a17SVictor Perevertkin 
8688a978a17SVictor Perevertkin     This method is used instead of relying on C++ static class
8698a978a17SVictor Perevertkin     constructors in kernel mode.
8708a978a17SVictor Perevertkin 
8718a978a17SVictor Perevertkin Arguments:
8728a978a17SVictor Perevertkin 
8738a978a17SVictor Perevertkin 
8748a978a17SVictor Perevertkin Returns:
8758a978a17SVictor Perevertkin 
8768a978a17SVictor Perevertkin     NTSTATUS
8778a978a17SVictor Perevertkin 
8788a978a17SVictor Perevertkin --*/
8798a978a17SVictor Perevertkin 
8808a978a17SVictor Perevertkin {
8818a978a17SVictor Perevertkin     NTSTATUS status;
8828a978a17SVictor Perevertkin     BOOLEAN windowsVerifierOn = FALSE;
8838a978a17SVictor Perevertkin 
8848a978a17SVictor Perevertkin     UNREFERENCED_PARAMETER(DriverConfig);
8858a978a17SVictor Perevertkin 
8868a978a17SVictor Perevertkin     //
8878a978a17SVictor Perevertkin     // Check if windows driver verifier is on for this driver
8888a978a17SVictor Perevertkin     // We need this when initializing wdf verifier
8898a978a17SVictor Perevertkin     //
8908a978a17SVictor Perevertkin     windowsVerifierOn = IsWindowsVerifierOn(DriverObject);
8918a978a17SVictor Perevertkin 
8928a978a17SVictor Perevertkin     //
8938a978a17SVictor Perevertkin     // Get registry values first since these effect the
8948a978a17SVictor Perevertkin     // rest of initialization
8958a978a17SVictor Perevertkin     //
8968a978a17SVictor Perevertkin     FxRegistrySettingsInitialize(FxDriverGlobals,
8978a978a17SVictor Perevertkin                                  RegistryPath,
8988a978a17SVictor Perevertkin                                  windowsVerifierOn);
8998a978a17SVictor Perevertkin 
9008a978a17SVictor Perevertkin     //
9018a978a17SVictor Perevertkin     // Initialize IFR logging
9028a978a17SVictor Perevertkin     //
903*1f377076SVictor Perevertkin     // FxIFRStart(FxDriverGlobals, RegistryPath, DriverObject); __REACTOS__
9048a978a17SVictor Perevertkin 
9058a978a17SVictor Perevertkin     DoTraceLevelMessage(FxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
9068a978a17SVictor Perevertkin                         "Initialize globals for %!wZ!", RegistryPath);
9078a978a17SVictor Perevertkin 
9088a978a17SVictor Perevertkin     //
9098a978a17SVictor Perevertkin     // Only first one initializes the frameworks globals
9108a978a17SVictor Perevertkin     //
9118a978a17SVictor Perevertkin     status = FxPoolPackageInitialize(FxDriverGlobals);
9128a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
9138a978a17SVictor Perevertkin         //
9148a978a17SVictor Perevertkin         // FxPoolPackageInitialize logs a message in case of failure so
9158a978a17SVictor Perevertkin         // we don't need to log failure here.
9168a978a17SVictor Perevertkin         //
917*1f377076SVictor Perevertkin         // FxIFRStop(FxDriverGlobals); __REACTOS__
9188a978a17SVictor Perevertkin         return status;
9198a978a17SVictor Perevertkin     }
9208a978a17SVictor Perevertkin 
9218a978a17SVictor Perevertkin     //
9228a978a17SVictor Perevertkin     // Lock verifier package
9238a978a17SVictor Perevertkin     //
9248a978a17SVictor Perevertkin     FxVerifierLockInitialize(FxDriverGlobals);
9258a978a17SVictor Perevertkin 
9268a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
9278a978a17SVictor Perevertkin     //
9288a978a17SVictor Perevertkin     // Cache driver info for bugcheck callback.
9298a978a17SVictor Perevertkin     //
9308a978a17SVictor Perevertkin     FxCacheBugCheckDriverInfo(FxDriverGlobals);
9318a978a17SVictor Perevertkin 
9328a978a17SVictor Perevertkin     //
9338a978a17SVictor Perevertkin     // Register for bugcheck callbacks.
9348a978a17SVictor Perevertkin     //
9358a978a17SVictor Perevertkin     FxRegisterBugCheckCallback(FxDriverGlobals, DriverObject);
9368a978a17SVictor Perevertkin #endif
9378a978a17SVictor Perevertkin 
9388a978a17SVictor Perevertkin     if  (NULL != RegistryPath) {
9398a978a17SVictor Perevertkin         if  (FALSE == FxDriverGlobals->IsCorrectVersionRegistered(RegistryPath))
9408a978a17SVictor Perevertkin             FxDriverGlobals->RegisterClientVersion(RegistryPath);
9418a978a17SVictor Perevertkin     }
9428a978a17SVictor Perevertkin 
9438a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
9448a978a17SVictor Perevertkin     if(FxDriverGlobals->FxVerifierOn){
9458a978a17SVictor Perevertkin         LockVerifierSection(FxDriverGlobals, RegistryPath);
9468a978a17SVictor Perevertkin     }
9478a978a17SVictor Perevertkin #endif
9488a978a17SVictor Perevertkin 
9498a978a17SVictor Perevertkin     return STATUS_SUCCESS;
9508a978a17SVictor Perevertkin }
9518a978a17SVictor Perevertkin 
9528a978a17SVictor Perevertkin BOOLEAN
IsWindowsVerifierOn(_In_ MdDriverObject DriverObject)9538a978a17SVictor Perevertkin IsWindowsVerifierOn(
9548a978a17SVictor Perevertkin     _In_ MdDriverObject DriverObject
9558a978a17SVictor Perevertkin     )
9568a978a17SVictor Perevertkin {
9578a978a17SVictor Perevertkin     BOOLEAN windowsVerifierOn = FALSE;
9588a978a17SVictor Perevertkin 
9598a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
9608a978a17SVictor Perevertkin     //
9618a978a17SVictor Perevertkin     // Check if windows driver verifier is on for this driver
9628a978a17SVictor Perevertkin     // We need this when initializing wdf verifier
9638a978a17SVictor Perevertkin     //
9648a978a17SVictor Perevertkin     windowsVerifierOn = MmIsDriverVerifying(DriverObject) ? TRUE: FALSE;
9658a978a17SVictor Perevertkin 
9668a978a17SVictor Perevertkin #else
9678a978a17SVictor Perevertkin     UNREFERENCED_PARAMETER(DriverObject);
9688a978a17SVictor Perevertkin 
9698a978a17SVictor Perevertkin     //
9708a978a17SVictor Perevertkin     // For user-mode we check if app verifier's verifier.dll is loaded in this
9718a978a17SVictor Perevertkin     // process (since app verifier doesn't provide any other way to detect its
9728a978a17SVictor Perevertkin     // presence).
9738a978a17SVictor Perevertkin     //
9748a978a17SVictor Perevertkin     windowsVerifierOn = (GetModuleHandleW(L"verifier.dll") == NULL ? FALSE : TRUE);
9758a978a17SVictor Perevertkin #endif
9768a978a17SVictor Perevertkin 
9778a978a17SVictor Perevertkin     return windowsVerifierOn;
9788a978a17SVictor Perevertkin }
9798a978a17SVictor Perevertkin 
9808a978a17SVictor Perevertkin VOID
FxDestroy(__in PFX_DRIVER_GLOBALS FxDriverGlobals)9818a978a17SVictor Perevertkin FxDestroy(
9828a978a17SVictor Perevertkin     __in PFX_DRIVER_GLOBALS FxDriverGlobals
9838a978a17SVictor Perevertkin     )
9848a978a17SVictor Perevertkin 
9858a978a17SVictor Perevertkin /*++
9868a978a17SVictor Perevertkin 
9878a978a17SVictor Perevertkin Routine Description:
9888a978a17SVictor Perevertkin 
9898a978a17SVictor Perevertkin     This is the global framework uninitialization routine.
9908a978a17SVictor Perevertkin 
9918a978a17SVictor Perevertkin     It is here for symmetry, and to allow a shared DLL based frameworks
9928a978a17SVictor Perevertkin     to unload safely.
9938a978a17SVictor Perevertkin 
9948a978a17SVictor Perevertkin Arguments:
9958a978a17SVictor Perevertkin 
9968a978a17SVictor Perevertkin 
9978a978a17SVictor Perevertkin Returns:
9988a978a17SVictor Perevertkin 
9998a978a17SVictor Perevertkin     NTSTATUS
10008a978a17SVictor Perevertkin 
10018a978a17SVictor Perevertkin --*/
10028a978a17SVictor Perevertkin 
10038a978a17SVictor Perevertkin {
10048a978a17SVictor Perevertkin     //
10058a978a17SVictor Perevertkin     // Release the last reference.
10068a978a17SVictor Perevertkin     //
1007*1f377076SVictor Perevertkin     FxDriverGlobals->RELEASE((PVOID)FxDestroy);
10088a978a17SVictor Perevertkin 
10098a978a17SVictor Perevertkin     //
10108a978a17SVictor Perevertkin     // Wait for everyone else to be done.
10118a978a17SVictor Perevertkin     //
10128a978a17SVictor Perevertkin     Mx::MxEnterCriticalRegion();
10138a978a17SVictor Perevertkin     FxDriverGlobals->DestroyEvent.WaitFor(Executive, KernelMode, FALSE, NULL);
10148a978a17SVictor Perevertkin     Mx::MxLeaveCriticalRegion();
10158a978a17SVictor Perevertkin 
10168a978a17SVictor Perevertkin     //
10178a978a17SVictor Perevertkin     // Lock verifier package
10188a978a17SVictor Perevertkin     //
10198a978a17SVictor Perevertkin     FxVerifierLockDestroy(FxDriverGlobals);
10208a978a17SVictor Perevertkin 
10218a978a17SVictor Perevertkin     //
10228a978a17SVictor Perevertkin     // Cleanup frameworks structures
10238a978a17SVictor Perevertkin     //
10248a978a17SVictor Perevertkin     FxPoolPackageDestroy(FxDriverGlobals);
10258a978a17SVictor Perevertkin 
10268a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
10278a978a17SVictor Perevertkin     //
10288a978a17SVictor Perevertkin     // Deregister from the bugcheck callbacks.
10298a978a17SVictor Perevertkin     //
10308a978a17SVictor Perevertkin     FxUnregisterBugCheckCallback(FxDriverGlobals);
10318a978a17SVictor Perevertkin 
10328a978a17SVictor Perevertkin     //
10338a978a17SVictor Perevertkin     // Purge driver info from bugcheck data.
10348a978a17SVictor Perevertkin     //
10358a978a17SVictor Perevertkin     FxPurgeBugCheckDriverInfo(FxDriverGlobals);
10368a978a17SVictor Perevertkin #endif
10378a978a17SVictor Perevertkin 
10388a978a17SVictor Perevertkin #if ((FX_CORE_MODE)==(FX_CORE_KERNEL_MODE))
10398a978a17SVictor Perevertkin     //
10408a978a17SVictor Perevertkin     // unlock verifier image sections
10418a978a17SVictor Perevertkin     //
10428a978a17SVictor Perevertkin     if(FxDriverGlobals->FxVerifierOn){
10438a978a17SVictor Perevertkin         UnlockVerifierSection(FxDriverGlobals);
10448a978a17SVictor Perevertkin     }
10458a978a17SVictor Perevertkin #endif
10468a978a17SVictor Perevertkin 
10478a978a17SVictor Perevertkin     return;
10488a978a17SVictor Perevertkin }
10498a978a17SVictor Perevertkin 
10508a978a17SVictor Perevertkin _Must_inspect_result_
10518a978a17SVictor Perevertkin PWDF_DRIVER_GLOBALS
FxAllocateDriverGlobals(VOID)10528a978a17SVictor Perevertkin FxAllocateDriverGlobals(
10538a978a17SVictor Perevertkin     VOID
10548a978a17SVictor Perevertkin     )
10558a978a17SVictor Perevertkin {
10568a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS  pFxDriverGlobals;
1057*1f377076SVictor Perevertkin     // KIRQL               irql;
10588a978a17SVictor Perevertkin     NTSTATUS            status;
10598a978a17SVictor Perevertkin 
10608a978a17SVictor Perevertkin     pFxDriverGlobals = (PFX_DRIVER_GLOBALS)
10618a978a17SVictor Perevertkin         MxMemory::MxAllocatePoolWithTag(NonPagedPool, sizeof(FX_DRIVER_GLOBALS), FX_TAG);
10628a978a17SVictor Perevertkin 
10638a978a17SVictor Perevertkin     if (pFxDriverGlobals == NULL) {
10648a978a17SVictor Perevertkin         return NULL;
10658a978a17SVictor Perevertkin     }
10668a978a17SVictor Perevertkin 
1067*1f377076SVictor Perevertkin     *pFxDriverGlobals = {};
10688a978a17SVictor Perevertkin 
10698a978a17SVictor Perevertkin     pFxDriverGlobals->Refcnt = 1;
10708a978a17SVictor Perevertkin 
10718a978a17SVictor Perevertkin     status = pFxDriverGlobals->DestroyEvent.Initialize(NotificationEvent, FALSE);
10728a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_USER_MODE)
10738a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
10748a978a17SVictor Perevertkin         MxMemory::MxFreePool(pFxDriverGlobals);
10758a978a17SVictor Perevertkin         return NULL;
10768a978a17SVictor Perevertkin     }
10778a978a17SVictor Perevertkin #else
10788a978a17SVictor Perevertkin     UNREFERENCED_PARAMETER(status);
10798a978a17SVictor Perevertkin #endif
10808a978a17SVictor Perevertkin 
10818a978a17SVictor Perevertkin     //
10828a978a17SVictor Perevertkin     // Initialize this new FxDriverGlobals structure.
10838a978a17SVictor Perevertkin     //
1084*1f377076SVictor Perevertkin #ifndef __REACTOS__
10858a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Acquire(&irql);
10868a978a17SVictor Perevertkin     InsertHeadList(&FxLibraryGlobals.FxDriverGlobalsList,
10878a978a17SVictor Perevertkin                    &pFxDriverGlobals->Linkage);
10888a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Release(irql);
1089*1f377076SVictor Perevertkin #endif
10908a978a17SVictor Perevertkin 
10918a978a17SVictor Perevertkin     pFxDriverGlobals->WdfHandleMask                  = FxHandleValueMask;
10928a978a17SVictor Perevertkin     pFxDriverGlobals->WdfVerifierAllocateFailCount   = (ULONG) -1;
10938a978a17SVictor Perevertkin     pFxDriverGlobals->Driver                         = NULL;
10948a978a17SVictor Perevertkin     pFxDriverGlobals->DebugExtension                 = NULL;
10958a978a17SVictor Perevertkin     pFxDriverGlobals->LibraryGlobals                 = &FxLibraryGlobals;
10968a978a17SVictor Perevertkin     pFxDriverGlobals->WdfLogHeader                   = NULL;
10978a978a17SVictor Perevertkin 
10988a978a17SVictor Perevertkin     //
10998a978a17SVictor Perevertkin     // Verifier settings.  Off by default.
11008a978a17SVictor Perevertkin     //
11018a978a17SVictor Perevertkin     pFxDriverGlobals->SetVerifierState(FALSE);
11028a978a17SVictor Perevertkin 
11038a978a17SVictor Perevertkin     //
11048a978a17SVictor Perevertkin     // By default don't apply latest-version restricted verifier checks
11058a978a17SVictor Perevertkin     // to downlevel version drivers.
11068a978a17SVictor Perevertkin     //
11078a978a17SVictor Perevertkin     pFxDriverGlobals->FxVerifyDownlevel              = FALSE;
11088a978a17SVictor Perevertkin 
11098a978a17SVictor Perevertkin     //
11108a978a17SVictor Perevertkin     // Verbose is separate knob
11118a978a17SVictor Perevertkin     //
11128a978a17SVictor Perevertkin     pFxDriverGlobals->FxVerboseOn                    = FALSE;
11138a978a17SVictor Perevertkin 
11148a978a17SVictor Perevertkin     //
11158a978a17SVictor Perevertkin     // Do not parent queue presented requests.
11168a978a17SVictor Perevertkin     // This performance optimization is on by default.
11178a978a17SVictor Perevertkin     //
11188a978a17SVictor Perevertkin     pFxDriverGlobals->FxRequestParentOptimizationOn  = TRUE;
11198a978a17SVictor Perevertkin 
11208a978a17SVictor Perevertkin     //
11218a978a17SVictor Perevertkin     // Enhanced verifier options. Off by default
11228a978a17SVictor Perevertkin     //
11238a978a17SVictor Perevertkin     pFxDriverGlobals->FxEnhancedVerifierOptions = 0;
11248a978a17SVictor Perevertkin 
11258a978a17SVictor Perevertkin     //
11268a978a17SVictor Perevertkin     // If FxVerifierDbgBreakOnError is true, WaitForSignal interrupts the
11278a978a17SVictor Perevertkin     // execution of the system after waiting for the specified number
11288a978a17SVictor Perevertkin     // of seconds. Developer will have an opportunity to validate the state
11298a978a17SVictor Perevertkin     // of the driver when breakpoint is hit. Developer can continue to wait
11308a978a17SVictor Perevertkin     // by entering 'g' in the debugger.
11318a978a17SVictor Perevertkin     //
11328a978a17SVictor Perevertkin     pFxDriverGlobals->FxVerifierDbgWaitForSignalTimeoutInSec = 60;
11338a978a17SVictor Perevertkin 
11348a978a17SVictor Perevertkin     //
11358a978a17SVictor Perevertkin     // Timeout used by the wake interrupt ISR in WaitForSignal to catch
11368a978a17SVictor Perevertkin     // scenarios where the interrupt ISR is blocked because the device stack
11378a978a17SVictor Perevertkin     // is taking too long to power up
11388a978a17SVictor Perevertkin     //
11398a978a17SVictor Perevertkin     pFxDriverGlobals->DbgWaitForWakeInterruptIsrTimeoutInSec = 60;
11408a978a17SVictor Perevertkin 
11418a978a17SVictor Perevertkin     //
11428a978a17SVictor Perevertkin     // Minidump log related settings.
11438a978a17SVictor Perevertkin     //
11448a978a17SVictor Perevertkin     pFxDriverGlobals->FxForceLogsInMiniDump          = FALSE;
11458a978a17SVictor Perevertkin 
11468a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
1147*1f377076SVictor Perevertkin     // pFxDriverGlobals->FxTrackDriverForMiniDumpLog    = TRUE;
1148*1f377076SVictor Perevertkin     pFxDriverGlobals->FxTrackDriverForMiniDumpLog    = FALSE; // __REACTOS__
11498a978a17SVictor Perevertkin     pFxDriverGlobals->IsUserModeDriver               = FALSE;
11508a978a17SVictor Perevertkin #else
11518a978a17SVictor Perevertkin     pFxDriverGlobals->FxTrackDriverForMiniDumpLog    = FALSE;
11528a978a17SVictor Perevertkin     pFxDriverGlobals->IsUserModeDriver               = TRUE;
11538a978a17SVictor Perevertkin #endif
11548a978a17SVictor Perevertkin 
11558a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
11568a978a17SVictor Perevertkin     //
11578a978a17SVictor Perevertkin     // Minidump driver info related settings.
11588a978a17SVictor Perevertkin     //
11598a978a17SVictor Perevertkin     pFxDriverGlobals->BugCheckDriverInfoIndex        = 0;
11608a978a17SVictor Perevertkin #endif
11618a978a17SVictor Perevertkin 
11628a978a17SVictor Perevertkin     //
11638a978a17SVictor Perevertkin     // By default disable the support for device simulation framework (DSF).
11648a978a17SVictor Perevertkin     //
11658a978a17SVictor Perevertkin     pFxDriverGlobals->FxDsfOn  = FALSE;
11668a978a17SVictor Perevertkin 
11678a978a17SVictor Perevertkin     //
11688a978a17SVictor Perevertkin     // Allocate a telemetry context if a telemetry client is enabled, for any level/keyword.
11698a978a17SVictor Perevertkin     //
11708a978a17SVictor Perevertkin     pFxDriverGlobals->TelemetryContext = NULL;
1171*1f377076SVictor Perevertkin #ifdef EVENT_TRACING // __REACTOS__
11728a978a17SVictor Perevertkin     if (TraceLoggingProviderEnabled(g_TelemetryProvider, 0 ,0)) {
11738a978a17SVictor Perevertkin         AllocAndInitializeTelemetryContext(&(pFxDriverGlobals->TelemetryContext));
11748a978a17SVictor Perevertkin     }
1175*1f377076SVictor Perevertkin #endif
11768a978a17SVictor Perevertkin 
11778a978a17SVictor Perevertkin     return &pFxDriverGlobals->Public;
11788a978a17SVictor Perevertkin }
11798a978a17SVictor Perevertkin 
11808a978a17SVictor Perevertkin VOID
FxFreeDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)11818a978a17SVictor Perevertkin FxFreeDriverGlobals(
11828a978a17SVictor Perevertkin     __in PWDF_DRIVER_GLOBALS DriverGlobals
11838a978a17SVictor Perevertkin     )
11848a978a17SVictor Perevertkin {
11858a978a17SVictor Perevertkin     PFX_DRIVER_GLOBALS pFxDriverGlobals;
11868a978a17SVictor Perevertkin     KIRQL irql;
11878a978a17SVictor Perevertkin 
11888a978a17SVictor Perevertkin     pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
11898a978a17SVictor Perevertkin 
11908a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Acquire(&irql);
11918a978a17SVictor Perevertkin     RemoveEntryList(&pFxDriverGlobals->Linkage);
11928a978a17SVictor Perevertkin     InitializeListHead(&pFxDriverGlobals->Linkage);
11938a978a17SVictor Perevertkin     FxLibraryGlobals.FxDriverGlobalsListLock.Release(irql);
11948a978a17SVictor Perevertkin 
11958a978a17SVictor Perevertkin     if (pFxDriverGlobals->DebugExtension != NULL) {
11968a978a17SVictor Perevertkin 
11978a978a17SVictor Perevertkin         FxFreeAllocatedMdlsDebugInfo(pFxDriverGlobals->DebugExtension);
11988a978a17SVictor Perevertkin 
11998a978a17SVictor Perevertkin         if (pFxDriverGlobals->DebugExtension->ObjectDebugInfo != NULL) {
12008a978a17SVictor Perevertkin             MxMemory::MxFreePool(pFxDriverGlobals->DebugExtension->ObjectDebugInfo);
12018a978a17SVictor Perevertkin             pFxDriverGlobals->DebugExtension->ObjectDebugInfo = NULL;
12028a978a17SVictor Perevertkin         }
12038a978a17SVictor Perevertkin 
12048a978a17SVictor Perevertkin         pFxDriverGlobals->DebugExtension->AllocatedTagTrackersLock.Uninitialize();
12058a978a17SVictor Perevertkin 
12068a978a17SVictor Perevertkin         MxMemory::MxFreePool(pFxDriverGlobals->DebugExtension);
12078a978a17SVictor Perevertkin         pFxDriverGlobals->DebugExtension = NULL;
12088a978a17SVictor Perevertkin     }
12098a978a17SVictor Perevertkin 
12108a978a17SVictor Perevertkin     //
12118a978a17SVictor Perevertkin     // Cleanup event b/c d'tor is not called for MxAllocatePoolWithTag.
12128a978a17SVictor Perevertkin     //
12138a978a17SVictor Perevertkin     pFxDriverGlobals->DestroyEvent.Uninitialize();
12148a978a17SVictor Perevertkin 
12158a978a17SVictor Perevertkin     if (NULL != pFxDriverGlobals->TelemetryContext) {
12168a978a17SVictor Perevertkin         MxMemory::MxFreePool(pFxDriverGlobals->TelemetryContext);
12178a978a17SVictor Perevertkin         pFxDriverGlobals->TelemetryContext = NULL;
12188a978a17SVictor Perevertkin     }
12198a978a17SVictor Perevertkin 
12208a978a17SVictor Perevertkin     MxMemory::MxFreePool(pFxDriverGlobals);
12218a978a17SVictor Perevertkin }
12228a978a17SVictor Perevertkin 
12238a978a17SVictor Perevertkin _Must_inspect_result_
12248a978a17SVictor Perevertkin FxObjectDebugInfo*
FxVerifierGetObjectDebugInfo(__in HANDLE Key,__in PFX_DRIVER_GLOBALS FxDriverGlobals)12258a978a17SVictor Perevertkin FxVerifierGetObjectDebugInfo(
12268a978a17SVictor Perevertkin     __in HANDLE Key,
12278a978a17SVictor Perevertkin     __in PFX_DRIVER_GLOBALS  FxDriverGlobals
12288a978a17SVictor Perevertkin     )
12298a978a17SVictor Perevertkin 
12308a978a17SVictor Perevertkin /*++
12318a978a17SVictor Perevertkin 
12328a978a17SVictor Perevertkin Routine Description:
12338a978a17SVictor Perevertkin     Attempts to open a value under the passed in key and create an array of
12348a978a17SVictor Perevertkin     FxObjectDebugInfo.
12358a978a17SVictor Perevertkin 
12368a978a17SVictor Perevertkin Arguments:
12378a978a17SVictor Perevertkin     Key - Registry key to query the value for
12388a978a17SVictor Perevertkin 
12398a978a17SVictor Perevertkin Return Value:
12408a978a17SVictor Perevertkin     NULL or a pointer which should be freed by the caller using ExFreePool
12418a978a17SVictor Perevertkin 
12428a978a17SVictor Perevertkin --*/
12438a978a17SVictor Perevertkin 
12448a978a17SVictor Perevertkin {
12458a978a17SVictor Perevertkin     FxObjectDebugInfo* pInfo;
12468a978a17SVictor Perevertkin     PVOID dataBuffer;
12478a978a17SVictor Perevertkin     NTSTATUS status;
12488a978a17SVictor Perevertkin     ULONG length, type;
12498a978a17SVictor Perevertkin     DECLARE_CONST_UNICODE_STRING(valueName, L"TrackHandles");
12508a978a17SVictor Perevertkin 
12518a978a17SVictor Perevertkin     pInfo = NULL;
12528a978a17SVictor Perevertkin     type = REG_MULTI_SZ;
12538a978a17SVictor Perevertkin     length = 0;
12548a978a17SVictor Perevertkin 
12558a978a17SVictor Perevertkin     //
12568a978a17SVictor Perevertkin     // Find out how big a buffer we need to allocate if the value is present
12578a978a17SVictor Perevertkin     //
12588a978a17SVictor Perevertkin     status = FxRegKey::_QueryValue(FxDriverGlobals,
12598a978a17SVictor Perevertkin                                    Key,
12608a978a17SVictor Perevertkin                                    &valueName,
12618a978a17SVictor Perevertkin                                    length,
12628a978a17SVictor Perevertkin                                    NULL,
12638a978a17SVictor Perevertkin                                    &length,
12648a978a17SVictor Perevertkin                                    &type);
12658a978a17SVictor Perevertkin 
12668a978a17SVictor Perevertkin     //
12678a978a17SVictor Perevertkin     // We expect the list to be bigger then a standard partial, so if it is
12688a978a17SVictor Perevertkin     // not, just bail now.
12698a978a17SVictor Perevertkin     //
12708a978a17SVictor Perevertkin     if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL) {
12718a978a17SVictor Perevertkin         return NULL;
12728a978a17SVictor Perevertkin     }
12738a978a17SVictor Perevertkin 
12748a978a17SVictor Perevertkin     //
12758a978a17SVictor Perevertkin     // Pool can be paged b/c we are running at PASSIVE_LEVEL and we are going
12768a978a17SVictor Perevertkin     // to free it at the end of this function.
12778a978a17SVictor Perevertkin     //
12788a978a17SVictor Perevertkin     dataBuffer = MxMemory::MxAllocatePoolWithTag(PagedPool, length, FxDriverGlobals->Tag);
12798a978a17SVictor Perevertkin     if (dataBuffer == NULL) {
12808a978a17SVictor Perevertkin         return NULL;
12818a978a17SVictor Perevertkin     }
12828a978a17SVictor Perevertkin 
12838a978a17SVictor Perevertkin     //
12848a978a17SVictor Perevertkin     // Requery now that we have a big enough buffer
12858a978a17SVictor Perevertkin     //
12868a978a17SVictor Perevertkin     status = FxRegKey::_QueryValue(FxDriverGlobals,
12878a978a17SVictor Perevertkin                                    Key,
12888a978a17SVictor Perevertkin                                    &valueName,
12898a978a17SVictor Perevertkin                                    length,
12908a978a17SVictor Perevertkin                                    dataBuffer,
12918a978a17SVictor Perevertkin                                    &length,
12928a978a17SVictor Perevertkin                                    &type);
12938a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
12948a978a17SVictor Perevertkin         //
12958a978a17SVictor Perevertkin         // Verify that the data from the registry is a valid multi-sz string.
12968a978a17SVictor Perevertkin         //
12978a978a17SVictor Perevertkin         status = FxRegKey::_VerifyMultiSzString(FxDriverGlobals,
12988a978a17SVictor Perevertkin                                                 &valueName,
12998a978a17SVictor Perevertkin                                                 (PWCHAR) dataBuffer,
13008a978a17SVictor Perevertkin                                                 length);
13018a978a17SVictor Perevertkin     }
13028a978a17SVictor Perevertkin 
13038a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
13048a978a17SVictor Perevertkin #pragma prefast(push)
13058a978a17SVictor Perevertkin #pragma prefast(suppress:__WARNING_PRECONDITION_NULLTERMINATION_VIOLATION, "FxRegKey::_VerifyMultiSzString makes sure the string is NULL-terminated")
13068a978a17SVictor Perevertkin         pInfo = FxVerifyAllocateDebugInfo((LPWSTR) dataBuffer, FxDriverGlobals);
13078a978a17SVictor Perevertkin #pragma prefast(pop)
13088a978a17SVictor Perevertkin 
13098a978a17SVictor Perevertkin     }
13108a978a17SVictor Perevertkin 
13118a978a17SVictor Perevertkin     MxMemory::MxFreePool(dataBuffer);
13128a978a17SVictor Perevertkin 
13138a978a17SVictor Perevertkin     return pInfo;
13148a978a17SVictor Perevertkin }
13158a978a17SVictor Perevertkin 
13168a978a17SVictor Perevertkin VOID
FxVerifierQueryTrackPower(__in HANDLE Key,__out FxTrackPowerOption * TrackPower)13178a978a17SVictor Perevertkin FxVerifierQueryTrackPower(
13188a978a17SVictor Perevertkin     __in HANDLE Key,
13198a978a17SVictor Perevertkin     __out FxTrackPowerOption* TrackPower
13208a978a17SVictor Perevertkin     )
13218a978a17SVictor Perevertkin {
13228a978a17SVictor Perevertkin     NTSTATUS status;
13238a978a17SVictor Perevertkin     ULONG value = 0;
13248a978a17SVictor Perevertkin     DECLARE_CONST_UNICODE_STRING(valueName, L"TrackPower");
13258a978a17SVictor Perevertkin 
13268a978a17SVictor Perevertkin     status = FxRegKey::_QueryULong(Key, &valueName, &value);
13278a978a17SVictor Perevertkin     if (NT_SUCCESS(status) && value < FxTrackPowerMaxValue) {
13288a978a17SVictor Perevertkin         *TrackPower = (FxTrackPowerOption)value;
13298a978a17SVictor Perevertkin     }
13308a978a17SVictor Perevertkin     else {
13318a978a17SVictor Perevertkin         *TrackPower = FxTrackPowerNone;
13328a978a17SVictor Perevertkin     }
13338a978a17SVictor Perevertkin }
13348a978a17SVictor Perevertkin 
13358a978a17SVictor Perevertkin VOID
FxOverrideDefaultVerifierSettings(__in HANDLE Key,__in LPWSTR Name,__out PBOOLEAN OverrideValue)13368a978a17SVictor Perevertkin FxOverrideDefaultVerifierSettings(
13378a978a17SVictor Perevertkin     __in    HANDLE Key,
13388a978a17SVictor Perevertkin     __in    LPWSTR Name,
13398a978a17SVictor Perevertkin     __out   PBOOLEAN OverrideValue
13408a978a17SVictor Perevertkin     )
13418a978a17SVictor Perevertkin {
13428a978a17SVictor Perevertkin     UNICODE_STRING valueName;
13438a978a17SVictor Perevertkin     ULONG value = 0;
13448a978a17SVictor Perevertkin 
13458a978a17SVictor Perevertkin     RtlInitUnicodeString(&valueName, Name);
13468a978a17SVictor Perevertkin 
13478a978a17SVictor Perevertkin     if (NT_SUCCESS(FxRegKey::_QueryULong(Key,
13488a978a17SVictor Perevertkin                                          (PCUNICODE_STRING)&valueName,
13498a978a17SVictor Perevertkin                                          &value))) {
13508a978a17SVictor Perevertkin         if (value) {
13518a978a17SVictor Perevertkin             *OverrideValue = TRUE;
13528a978a17SVictor Perevertkin         } else {
13538a978a17SVictor Perevertkin             *OverrideValue = FALSE;
13548a978a17SVictor Perevertkin         }
13558a978a17SVictor Perevertkin     }
13568a978a17SVictor Perevertkin 
13578a978a17SVictor Perevertkin }
13588a978a17SVictor Perevertkin 
13598a978a17SVictor Perevertkin 
13608a978a17SVictor Perevertkin VOID
FxRegistrySettingsInitialize(__inout PFX_DRIVER_GLOBALS FxDriverGlobals,__in PCUNICODE_STRING RegistryPath,__in BOOLEAN WindowsVerifierOn)13618a978a17SVictor Perevertkin FxRegistrySettingsInitialize(
13628a978a17SVictor Perevertkin     __inout PFX_DRIVER_GLOBALS FxDriverGlobals,
13638a978a17SVictor Perevertkin     __in PCUNICODE_STRING RegistryPath,
13648a978a17SVictor Perevertkin     __in BOOLEAN WindowsVerifierOn
13658a978a17SVictor Perevertkin     )
13668a978a17SVictor Perevertkin 
13678a978a17SVictor Perevertkin /*++
13688a978a17SVictor Perevertkin 
13698a978a17SVictor Perevertkin Routine Description:
13708a978a17SVictor Perevertkin 
13718a978a17SVictor Perevertkin     Initialize Driver Framework settings from the driver
13728a978a17SVictor Perevertkin     specific registry settings under
13738a978a17SVictor Perevertkin 
13748a978a17SVictor Perevertkin     \REGISTRY\MACHINE\SYSTEM\ControlSetxxx\Services\<driver>\Parameters\Wdf
13758a978a17SVictor Perevertkin 
13768a978a17SVictor Perevertkin Arguments:
13778a978a17SVictor Perevertkin 
13788a978a17SVictor Perevertkin     RegistryPath - Registry path passed to DriverEntry
13798a978a17SVictor Perevertkin 
13808a978a17SVictor Perevertkin --*/
13818a978a17SVictor Perevertkin 
13828a978a17SVictor Perevertkin {
13838a978a17SVictor Perevertkin     NTSTATUS status;
13848a978a17SVictor Perevertkin     RTL_QUERY_REGISTRY_TABLE paramTable[10];
13858a978a17SVictor Perevertkin     ULONG verifierOnValue;
13868a978a17SVictor Perevertkin     ULONG verifyDownlevelValue;
13878a978a17SVictor Perevertkin     ULONG verboseValue;
13888a978a17SVictor Perevertkin     ULONG allocateFailValue;
13898a978a17SVictor Perevertkin     ULONG forceLogsInMiniDump;
13908a978a17SVictor Perevertkin     ULONG trackDriverForMiniDumpLog;
13918a978a17SVictor Perevertkin     ULONG requestParentOptimizationOn;
13928a978a17SVictor Perevertkin     ULONG dsfValue;
13938a978a17SVictor Perevertkin     ULONG removeLockOptionFlags;
13948a978a17SVictor Perevertkin     ULONG zero = 0;
13958a978a17SVictor Perevertkin     ULONG max = 0xFFFFFFFF;
13968a978a17SVictor Perevertkin     ULONG defaultTrue = (ULONG) TRUE;
13978a978a17SVictor Perevertkin     ULONG i;
13988a978a17SVictor Perevertkin     ULONG timeoutValue = 0;
13998a978a17SVictor Perevertkin     FxAutoRegKey hDriver, hWdf;
14008a978a17SVictor Perevertkin     DECLARE_CONST_UNICODE_STRING(parametersPath, L"Parameters\\Wdf");
14018a978a17SVictor Perevertkin 
14028a978a17SVictor Perevertkin     typedef NTSTATUS NTAPI QUERYFN(
14038a978a17SVictor Perevertkin         ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID);
14048a978a17SVictor Perevertkin 
14058a978a17SVictor Perevertkin     QUERYFN* queryFn;
14068a978a17SVictor Perevertkin 
14078a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
14088a978a17SVictor Perevertkin     UNICODE_STRING FunctionName;
14098a978a17SVictor Perevertkin #endif
14108a978a17SVictor Perevertkin 
14118a978a17SVictor Perevertkin     //
14128a978a17SVictor Perevertkin     // UMDF may not provide this registry path
14138a978a17SVictor Perevertkin     //
14148a978a17SVictor Perevertkin     if (NULL == RegistryPath) {
14158a978a17SVictor Perevertkin         return;
14168a978a17SVictor Perevertkin     }
14178a978a17SVictor Perevertkin 
14188a978a17SVictor Perevertkin     status = FxRegKey::_OpenKey(NULL, RegistryPath, &hDriver.m_Key, KEY_READ);
14198a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
14208a978a17SVictor Perevertkin         return;
14218a978a17SVictor Perevertkin     }
14228a978a17SVictor Perevertkin 
14238a978a17SVictor Perevertkin     status = FxRegKey::_OpenKey(hDriver.m_Key, &parametersPath, &hWdf.m_Key, KEY_READ);
14248a978a17SVictor Perevertkin     if (!NT_SUCCESS(status)) {
14258a978a17SVictor Perevertkin         //
14268a978a17SVictor Perevertkin         // For version >= 1.9 we enable WDF verifier automatically when driver
14278a978a17SVictor Perevertkin         // verifier or app verifier is enabled. Since inbox drivers may not have
14288a978a17SVictor Perevertkin         // WDF subkey populated as they may not use INF, we need to enable
14298a978a17SVictor Perevertkin         // verifier even if we fail to open wdf subkey (if DriverVerifier is on).
14308a978a17SVictor Perevertkin         //
14318a978a17SVictor Perevertkin         if (FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,9)) {
14328a978a17SVictor Perevertkin             //
14338a978a17SVictor Perevertkin             // Verifier settings are all or nothing.  We currently do not support
14348a978a17SVictor Perevertkin             // turning on individual sub-verifiers.
14358a978a17SVictor Perevertkin             //
14368a978a17SVictor Perevertkin             FxDriverGlobals->SetVerifierState(WindowsVerifierOn);
14378a978a17SVictor Perevertkin             if (FxDriverGlobals->FxVerifierOn) {
14388a978a17SVictor Perevertkin                 FxDriverGlobalsInitializeDebugExtension(FxDriverGlobals, NULL);
14398a978a17SVictor Perevertkin             }
14408a978a17SVictor Perevertkin         }
14418a978a17SVictor Perevertkin 
14428a978a17SVictor Perevertkin         return;
14438a978a17SVictor Perevertkin     }
14448a978a17SVictor Perevertkin 
14458a978a17SVictor Perevertkin     RtlZeroMemory (&paramTable[0], sizeof(paramTable));
14468a978a17SVictor Perevertkin     i = 0;
14478a978a17SVictor Perevertkin 
14488a978a17SVictor Perevertkin     verboseValue = 0;
14498a978a17SVictor Perevertkin 
14508a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
14518a978a17SVictor Perevertkin     paramTable[i].Name          = L"VerboseOn";
14528a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &verboseValue;
14538a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
14548a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &zero;
14558a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
14568a978a17SVictor Perevertkin 
14578a978a17SVictor Perevertkin     allocateFailValue = (ULONG) -1;
14588a978a17SVictor Perevertkin     i++;
14598a978a17SVictor Perevertkin 
14608a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
14618a978a17SVictor Perevertkin     paramTable[i].Name          = L"VerifierAllocateFailCount";
14628a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &allocateFailValue;
14638a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
14648a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &max;
14658a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
14668a978a17SVictor Perevertkin 
14678a978a17SVictor Perevertkin     verifierOnValue = 0;
14688a978a17SVictor Perevertkin 
14698a978a17SVictor Perevertkin     //
14708a978a17SVictor Perevertkin     // If the client version is 1.9 or above, the defaut (i.e when
14718a978a17SVictor Perevertkin     // the key is not present) VerifierOn state is tied to the
14728a978a17SVictor Perevertkin     // driver verifier.
14738a978a17SVictor Perevertkin     //
14748a978a17SVictor Perevertkin     if (FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,9)) {
14758a978a17SVictor Perevertkin         verifierOnValue = WindowsVerifierOn;
14768a978a17SVictor Perevertkin     }
14778a978a17SVictor Perevertkin 
14788a978a17SVictor Perevertkin     i++;
14798a978a17SVictor Perevertkin 
14808a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
14818a978a17SVictor Perevertkin     paramTable[i].Name          = L"VerifierOn";
14828a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &verifierOnValue;
14838a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
14848a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &verifierOnValue;
14858a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
14868a978a17SVictor Perevertkin 
14878a978a17SVictor Perevertkin     verifyDownlevelValue = 0;
14888a978a17SVictor Perevertkin     i++;
14898a978a17SVictor Perevertkin 
14908a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
14918a978a17SVictor Perevertkin     paramTable[i].Name          = L"VerifyDownLevel";
14928a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &verifyDownlevelValue;
14938a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
14948a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &zero;
14958a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
14968a978a17SVictor Perevertkin 
14978a978a17SVictor Perevertkin     forceLogsInMiniDump = 0;
14988a978a17SVictor Perevertkin     i++;
14998a978a17SVictor Perevertkin 
15008a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
15018a978a17SVictor Perevertkin     paramTable[i].Name          = L"ForceLogsInMiniDump";
15028a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &forceLogsInMiniDump;
15038a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
15048a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &zero;
15058a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
15068a978a17SVictor Perevertkin 
15078a978a17SVictor Perevertkin     //
15088a978a17SVictor Perevertkin     // Track driver for minidump log:
15098a978a17SVictor Perevertkin     //  Default for KMDF is on.
15108a978a17SVictor Perevertkin     //  Default for UMDF is off.
15118a978a17SVictor Perevertkin     //
15128a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
15138a978a17SVictor Perevertkin     trackDriverForMiniDumpLog = (ULONG) TRUE;
15148a978a17SVictor Perevertkin #else
15158a978a17SVictor Perevertkin     trackDriverForMiniDumpLog = 0;
15168a978a17SVictor Perevertkin #endif
15178a978a17SVictor Perevertkin     i++;
15188a978a17SVictor Perevertkin 
15198a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
15208a978a17SVictor Perevertkin     paramTable[i].Name          = L"TrackDriverForMiniDumpLog";
15218a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &trackDriverForMiniDumpLog;
15228a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
15238a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
15248a978a17SVictor Perevertkin     paramTable[i].DefaultData    = &defaultTrue;
15258a978a17SVictor Perevertkin #else
15268a978a17SVictor Perevertkin     paramTable[i].DefaultData    = &zero;
15278a978a17SVictor Perevertkin #endif
15288a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
15298a978a17SVictor Perevertkin 
15308a978a17SVictor Perevertkin     requestParentOptimizationOn = (ULONG) TRUE;
15318a978a17SVictor Perevertkin     i++;
15328a978a17SVictor Perevertkin 
15338a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
15348a978a17SVictor Perevertkin     paramTable[i].Name          = L"RequestParentOptimizationOn";
15358a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &requestParentOptimizationOn;
15368a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
15378a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &defaultTrue;
15388a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
15398a978a17SVictor Perevertkin 
15408a978a17SVictor Perevertkin     dsfValue = 0;
15418a978a17SVictor Perevertkin     i++;
15428a978a17SVictor Perevertkin 
15438a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
15448a978a17SVictor Perevertkin     paramTable[i].Name          = L"DsfOn";
15458a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &dsfValue;
15468a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
15478a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &zero;
15488a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
15498a978a17SVictor Perevertkin 
15508a978a17SVictor Perevertkin     removeLockOptionFlags = 0;
15518a978a17SVictor Perevertkin     i++;
15528a978a17SVictor Perevertkin 
15538a978a17SVictor Perevertkin     paramTable[i].Flags         = RTL_QUERY_REGISTRY_DIRECT;
15548a978a17SVictor Perevertkin     paramTable[i].Name          = L"RemoveLockOptionFlags";
15558a978a17SVictor Perevertkin     paramTable[i].EntryContext  = &removeLockOptionFlags;
15568a978a17SVictor Perevertkin     paramTable[i].DefaultType   = REG_DWORD;
15578a978a17SVictor Perevertkin     paramTable[i].DefaultData   = &zero;
15588a978a17SVictor Perevertkin     paramTable[i].DefaultLength = sizeof(ULONG);
15598a978a17SVictor Perevertkin 
15608a978a17SVictor Perevertkin     ASSERT(i < sizeof(paramTable) / sizeof(paramTable[0]));
15618a978a17SVictor Perevertkin 
15628a978a17SVictor Perevertkin #if (FX_CORE_MODE==FX_CORE_USER_MODE)
15638a978a17SVictor Perevertkin 
15648a978a17SVictor Perevertkin     queryFn = (QUERYFN*) GetProcAddress(
15658a978a17SVictor Perevertkin         GetModuleHandle(TEXT("ntdll.dll")),
15668a978a17SVictor Perevertkin         "RtlQueryRegistryValuesEx"
15678a978a17SVictor Perevertkin         );
15688a978a17SVictor Perevertkin 
15698a978a17SVictor Perevertkin #else
15708a978a17SVictor Perevertkin 
15718a978a17SVictor Perevertkin     RtlInitUnicodeString(&FunctionName, L"RtlQueryRegistryValuesEx");
15728a978a17SVictor Perevertkin 
15738a978a17SVictor Perevertkin #pragma warning(push)
15748a978a17SVictor Perevertkin #pragma warning(disable: 4055)
15758a978a17SVictor Perevertkin 
15768a978a17SVictor Perevertkin     queryFn  = (QUERYFN*)MmGetSystemRoutineAddress(&FunctionName);
15778a978a17SVictor Perevertkin 
15788a978a17SVictor Perevertkin #pragma warning(pop)
15798a978a17SVictor Perevertkin 
15808a978a17SVictor Perevertkin #endif
15818a978a17SVictor Perevertkin 
15828a978a17SVictor Perevertkin     if (queryFn == NULL) {
15838a978a17SVictor Perevertkin         queryFn = &RtlQueryRegistryValues;
15848a978a17SVictor Perevertkin     }
15858a978a17SVictor Perevertkin 
15868a978a17SVictor Perevertkin     status = queryFn(
15878a978a17SVictor Perevertkin         RTL_REGISTRY_OPTIONAL | RTL_REGISTRY_HANDLE,
15888a978a17SVictor Perevertkin         (PWSTR) hWdf.m_Key,
15898a978a17SVictor Perevertkin         &paramTable[0],
15908a978a17SVictor Perevertkin         NULL,
15918a978a17SVictor Perevertkin         NULL
15928a978a17SVictor Perevertkin         );
15938a978a17SVictor Perevertkin 
15948a978a17SVictor Perevertkin     //
15958a978a17SVictor Perevertkin     // Only examine key values on success
15968a978a17SVictor Perevertkin     //
15978a978a17SVictor Perevertkin     if (NT_SUCCESS(status)) {
15988a978a17SVictor Perevertkin 
15998a978a17SVictor Perevertkin         if (verboseValue) {
16008a978a17SVictor Perevertkin             FxDriverGlobals->FxVerboseOn = TRUE;
16018a978a17SVictor Perevertkin         }
16028a978a17SVictor Perevertkin         else {
16038a978a17SVictor Perevertkin             FxDriverGlobals->FxVerboseOn = FALSE;
16048a978a17SVictor Perevertkin         }
16058a978a17SVictor Perevertkin 
16068a978a17SVictor Perevertkin         if (allocateFailValue != (ULONG) -1) {
16078a978a17SVictor Perevertkin             FxDriverGlobals->WdfVerifierAllocateFailCount = (LONG) allocateFailValue;
16088a978a17SVictor Perevertkin         }
16098a978a17SVictor Perevertkin         else {
16108a978a17SVictor Perevertkin             FxDriverGlobals->WdfVerifierAllocateFailCount = -1;
16118a978a17SVictor Perevertkin         }
16128a978a17SVictor Perevertkin 
16138a978a17SVictor Perevertkin         //
16148a978a17SVictor Perevertkin         // Verifier settings are all or nothing.  We currently do not support
16158a978a17SVictor Perevertkin         // turning on individual sub-verifiers.
16168a978a17SVictor Perevertkin         //
16178a978a17SVictor Perevertkin         FxDriverGlobals->SetVerifierState(verifierOnValue ? TRUE : FALSE);
16188a978a17SVictor Perevertkin 
16198a978a17SVictor Perevertkin         if (FxDriverGlobals->FxVerifierOn) {
16208a978a17SVictor Perevertkin             FxDriverGlobalsInitializeDebugExtension(FxDriverGlobals, hWdf.m_Key);
16218a978a17SVictor Perevertkin         }
16228a978a17SVictor Perevertkin 
16238a978a17SVictor Perevertkin         //
16248a978a17SVictor Perevertkin         // Update FxVerifyDownLevel independent of FxVerifyOn because for UMDF
16258a978a17SVictor Perevertkin         // verifer is always on so it does not consume FxVerifyOn value
16268a978a17SVictor Perevertkin         //
16278a978a17SVictor Perevertkin         if (verifyDownlevelValue) {
16288a978a17SVictor Perevertkin             FxDriverGlobals->FxVerifyDownlevel = TRUE;
16298a978a17SVictor Perevertkin         }
16308a978a17SVictor Perevertkin         else {
16318a978a17SVictor Perevertkin             FxDriverGlobals->FxVerifyDownlevel = FALSE;
16328a978a17SVictor Perevertkin         }
16338a978a17SVictor Perevertkin 
16348a978a17SVictor Perevertkin         //
16358a978a17SVictor Perevertkin         // See if there exists an override in the registry for WDFVERIFY state.
16368a978a17SVictor Perevertkin         // We query for this separately so that we can establish a default state
16378a978a17SVictor Perevertkin         // based on verifierOnValue, and then know if the value was present in
16388a978a17SVictor Perevertkin         // the registry to override the default.
16398a978a17SVictor Perevertkin         //
16408a978a17SVictor Perevertkin         FxOverrideDefaultVerifierSettings(hWdf.m_Key,
16418a978a17SVictor Perevertkin                                           L"VerifyOn",
16428a978a17SVictor Perevertkin                                           &FxDriverGlobals->FxVerifyOn);
16438a978a17SVictor Perevertkin 
16448a978a17SVictor Perevertkin         if (FxDriverGlobals->FxVerifyOn) {
16458a978a17SVictor Perevertkin             FxDriverGlobals->Public.DriverFlags |= WdfVerifyOn;
16468a978a17SVictor Perevertkin         }
16478a978a17SVictor Perevertkin 
16488a978a17SVictor Perevertkin         FxOverrideDefaultVerifierSettings(hWdf.m_Key,
16498a978a17SVictor Perevertkin                                           L"DbgBreakOnError",
16508a978a17SVictor Perevertkin                                           &FxDriverGlobals->FxVerifierDbgBreakOnError);
16518a978a17SVictor Perevertkin 
16528a978a17SVictor Perevertkin         FxOverrideDefaultVerifierSettings(hWdf.m_Key,
16538a978a17SVictor Perevertkin                                           L"DbgBreakOnDeviceStateError",
16548a978a17SVictor Perevertkin                                           &FxDriverGlobals->FxVerifierDbgBreakOnDeviceStateError);
16558a978a17SVictor Perevertkin 
16568a978a17SVictor Perevertkin         if (FxDriverGlobals->FxVerifierDbgBreakOnError) {
16578a978a17SVictor Perevertkin             timeoutValue = 0;
16588a978a17SVictor Perevertkin             DECLARE_CONST_UNICODE_STRING(timeoutName, L"DbgWaitForSignalTimeoutInSec");
16598a978a17SVictor Perevertkin 
16608a978a17SVictor Perevertkin             //
16618a978a17SVictor Perevertkin             // Get the override value for the WaitForSignal's timeout if present.
16628a978a17SVictor Perevertkin             //
16638a978a17SVictor Perevertkin             if (NT_SUCCESS(FxRegKey::_QueryULong(hWdf.m_Key,
16648a978a17SVictor Perevertkin                                                  &timeoutName,
16658a978a17SVictor Perevertkin                                                  &timeoutValue))) {
16668a978a17SVictor Perevertkin 
16678a978a17SVictor Perevertkin                 FxDriverGlobals->FxVerifierDbgWaitForSignalTimeoutInSec = timeoutValue;
16688a978a17SVictor Perevertkin             }
16698a978a17SVictor Perevertkin         }
16708a978a17SVictor Perevertkin 
16718a978a17SVictor Perevertkin         timeoutValue = 0;
16728a978a17SVictor Perevertkin         DECLARE_CONST_UNICODE_STRING(timeoutName, L"DbgWaitForWakeInterruptIsrTimeoutInSec");
16738a978a17SVictor Perevertkin 
16748a978a17SVictor Perevertkin         //
16758a978a17SVictor Perevertkin         // Get the override value for the Wake Interrupt ISR timeout if present.
16768a978a17SVictor Perevertkin         // Since the wake interrupt feature is only supported for 1.13 and higher,
16778a978a17SVictor Perevertkin         // avoid querying the reg key for older versions
16788a978a17SVictor Perevertkin         //
16798a978a17SVictor Perevertkin         if (FxDriverGlobals->IsVersionGreaterThanOrEqualTo(1,13) &&
16808a978a17SVictor Perevertkin             NT_SUCCESS(FxRegKey::_QueryULong(hWdf.m_Key,
16818a978a17SVictor Perevertkin                                              &timeoutName,
16828a978a17SVictor Perevertkin                                              &timeoutValue))) {
16838a978a17SVictor Perevertkin 
16848a978a17SVictor Perevertkin             FxDriverGlobals->DbgWaitForWakeInterruptIsrTimeoutInSec = timeoutValue;
16858a978a17SVictor Perevertkin         }
16868a978a17SVictor Perevertkin 
16878a978a17SVictor Perevertkin         FxDriverGlobals->FxForceLogsInMiniDump =
16888a978a17SVictor Perevertkin                             (forceLogsInMiniDump) ? TRUE : FALSE;
16898a978a17SVictor Perevertkin 
16908a978a17SVictor Perevertkin         FxDriverGlobals->FxTrackDriverForMiniDumpLog =
16918a978a17SVictor Perevertkin                             (trackDriverForMiniDumpLog) ? TRUE : FALSE;
16928a978a17SVictor Perevertkin 
16938a978a17SVictor Perevertkin         FxDriverGlobals->FxRequestParentOptimizationOn =
16948a978a17SVictor Perevertkin                             (requestParentOptimizationOn) ? TRUE : FALSE;
16958a978a17SVictor Perevertkin 
16968a978a17SVictor Perevertkin         FxDriverGlobals->FxDsfOn = (dsfValue) ? TRUE : FALSE;
16978a978a17SVictor Perevertkin 
16988a978a17SVictor Perevertkin         FxDriverGlobals->RemoveLockOptionFlags = removeLockOptionFlags;
16998a978a17SVictor Perevertkin     }
17008a978a17SVictor Perevertkin 
17018a978a17SVictor Perevertkin     return;
17028a978a17SVictor Perevertkin }
17038a978a17SVictor Perevertkin 
17048a978a17SVictor Perevertkin VOID
WaitForSignal(__in MxEvent * Event,__in PCSTR ReasonForWaiting,__in WDFOBJECT Handle,__in ULONG WarningTimeoutInSec,__in ULONG WaitSignalFlags)17058a978a17SVictor Perevertkin FX_DRIVER_GLOBALS::WaitForSignal(
17068a978a17SVictor Perevertkin     __in MxEvent* Event,
17078a978a17SVictor Perevertkin     __in PCSTR ReasonForWaiting,
17088a978a17SVictor Perevertkin     __in WDFOBJECT Handle,
17098a978a17SVictor Perevertkin     __in ULONG WarningTimeoutInSec,
17108a978a17SVictor Perevertkin     __in ULONG WaitSignalFlags
17118a978a17SVictor Perevertkin     )
17128a978a17SVictor Perevertkin {
17138a978a17SVictor Perevertkin     LARGE_INTEGER timeOut;
17148a978a17SVictor Perevertkin     NTSTATUS status;
17158a978a17SVictor Perevertkin 
17168a978a17SVictor Perevertkin     ASSERT(Mx::MxGetCurrentIrql() == PASSIVE_LEVEL);
17178a978a17SVictor Perevertkin 
17188a978a17SVictor Perevertkin     timeOut.QuadPart = WDF_REL_TIMEOUT_IN_SEC(((ULONGLONG)WarningTimeoutInSec));
17198a978a17SVictor Perevertkin 
17208a978a17SVictor Perevertkin     do {
17218a978a17SVictor Perevertkin         status = Event->WaitFor(Executive,
17228a978a17SVictor Perevertkin                         KernelMode,
17238a978a17SVictor Perevertkin                         FALSE, // Non alertable
17248a978a17SVictor Perevertkin                         timeOut.QuadPart ? &timeOut : NULL);
17258a978a17SVictor Perevertkin 
17268a978a17SVictor Perevertkin         if(status == STATUS_TIMEOUT) {
17278a978a17SVictor Perevertkin             DbgPrint("Thread 0x%p is %s 0x%p\n",
17288a978a17SVictor Perevertkin 		      Mx::MxGetCurrentThread(),
17298a978a17SVictor Perevertkin                       ReasonForWaiting,
17308a978a17SVictor Perevertkin                       Handle);
17318a978a17SVictor Perevertkin 
17328a978a17SVictor Perevertkin             if ((WaitSignalFlags & WaitSignalAlwaysBreak) ||
17338a978a17SVictor Perevertkin                 ((WaitSignalFlags & WaitSignalBreakUnderVerifier) &&
17348a978a17SVictor Perevertkin                  FxVerifierDbgBreakOnError) ||
17358a978a17SVictor Perevertkin                 ((WaitSignalFlags & WaitSignalBreakUnderDebugger) &&
17368a978a17SVictor Perevertkin                  IsDebuggerAttached())) {
17378a978a17SVictor Perevertkin 
17388a978a17SVictor Perevertkin                 DbgBreakPoint();
17398a978a17SVictor Perevertkin             }
17408a978a17SVictor Perevertkin         } else {
17418a978a17SVictor Perevertkin             ASSERT(NT_SUCCESS(status));
17428a978a17SVictor Perevertkin             break;
17438a978a17SVictor Perevertkin         }
17448a978a17SVictor Perevertkin     } WHILE(TRUE);
17458a978a17SVictor Perevertkin }
17468a978a17SVictor Perevertkin 
17478a978a17SVictor Perevertkin } // extern "C"
1748