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, ¶metersPath, &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 (¶mTable[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 ¶mTable[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