1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxObjectUm.cpp 8 9 Abstract: 10 11 User mode implementations of FxObject APIs 12 13 Author: 14 15 16 Environment: 17 18 user mode only 19 20 Revision History: 21 22 --*/ 23 24 #include "fxobjectpch.hpp" 25 26 extern "C" { 27 28 #if defined(EVENT_TRACING) 29 #include "FxObjectUm.tmh" 30 #endif 31 32 } 33 34 extern "C" { 35 36 #define INITGUID 37 #include <guiddef.h> 38 39 #include <WdfFileObject_private.h> 40 41 // 42 // Function declarations for the WdfObjectQuery DDIs 43 // 44 _IRQL_requires_max_(PASSIVE_LEVEL) 45 WDFAPI 46 NTSTATUS 47 WDFEXPORT(WdfFileObjectIncrementProcessKeepAliveCount)( 48 _In_ 49 PWDF_DRIVER_GLOBALS DriverGlobals, 50 _In_ 51 WDFFILEOBJECT FileObject 52 ); 53 54 _IRQL_requires_max_(PASSIVE_LEVEL) 55 WDFAPI 56 NTSTATUS 57 WDFEXPORT(WdfFileObjectDecrementProcessKeepAliveCount)( 58 _In_ 59 PWDF_DRIVER_GLOBALS DriverGlobals, 60 _In_ 61 WDFFILEOBJECT FileObject 62 ); 63 64 } 65 66 67 extern "C" { 68 69 _Must_inspect_result_ 70 NTSTATUS 71 FxObject::_ObjectQuery( 72 _In_ FxObject* Object, 73 _In_ CONST GUID* Guid, 74 _In_ ULONG QueryBufferLength, 75 _Out_writes_bytes_(QueryBufferLength) 76 PVOID QueryBuffer 77 ) 78 79 /*++ 80 81 Routine Description: 82 83 Query the object handle for specific information 84 85 This allows dynamic extensions to DDI's. 86 87 Currently, it is used to allow test hooks for verification 88 which are not available in a production release. 89 90 Arguments: 91 92 Object - Object to query 93 94 Guid - GUID to represent the information/DDI to query for 95 96 QueryBufferLength - Length of QueryBuffer to return data in 97 98 QueryBuffer - Pointer to QueryBuffer 99 100 Returns: 101 102 NTSTATUS 103 104 --*/ 105 106 { 107 PFX_DRIVER_GLOBALS pFxDriverGlobals = Object->GetDriverGlobals(); 108 109 // 110 // Design Note: This interface does not look strongly typed 111 // but it is. The GUID defines a specific strongly typed 112 // contract for QueryBuffer and QueryBufferLength. 113 // 114 115 #if DBG 116 117 // 118 // These operations are only available on checked builds for deep unit 119 // testing, code coverage analysis, and model verification. 120 121 122 123 124 125 126 127 128 129 130 131 132 133 // 134 135 // Add code based on the GUID 136 137 // IsEqualGUID(guid1, guid2), DEFINE_GUID, INITGUID, inc\wnet\guiddef.h 138 #endif 139 140 if (IsEqualGUID(*Guid, GUID_WDFP_FILEOBJECT_INTERFACE)) { 141 142 // 143 // Check the query buffer size before performing the cast 144 // 145 const ULONG RequiredBufferLength = sizeof(WDFP_FILEOBJECT_INTERFACE); 146 147 if (QueryBufferLength < RequiredBufferLength) { 148 DoTraceLevelMessage( 149 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 150 "Insufficient query buffer size for file object query " 151 "Required size %d, %!STATUS!", 152 RequiredBufferLength, 153 STATUS_BUFFER_TOO_SMALL); 154 FxVerifierDbgBreakPoint(pFxDriverGlobals); 155 return STATUS_BUFFER_TOO_SMALL; 156 } 157 158 if (nullptr == QueryBuffer) { 159 DoTraceLevelMessage( 160 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 161 "NULL query buffer for file object query, %!STATUS!", 162 STATUS_BUFFER_TOO_SMALL); 163 FxVerifierDbgBreakPoint(pFxDriverGlobals); 164 return STATUS_INVALID_PARAMETER; 165 } 166 167 PWDFP_FILEOBJECT_INTERFACE FileObjectInterface = 168 reinterpret_cast<PWDFP_FILEOBJECT_INTERFACE>(QueryBuffer); 169 170 // 171 // Check the struct version (require an exact match for a private DDI) 172 // 173 if (FileObjectInterface->Size != RequiredBufferLength) { 174 DoTraceLevelMessage( 175 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGDEVICE, 176 "Wrong struct version provided for file object query, " 177 "%!STATUS!", 178 STATUS_INVALID_PARAMETER); 179 FxVerifierDbgBreakPoint(pFxDriverGlobals); 180 return STATUS_INVALID_PARAMETER; 181 } 182 183 FileObjectInterface->WdfpFileObjectIncrementProcessKeepAliveCount = 184 WDFEXPORT(WdfFileObjectIncrementProcessKeepAliveCount); 185 FileObjectInterface->WdfpFileObjectDecrementProcessKeepAliveCount = 186 WDFEXPORT(WdfFileObjectDecrementProcessKeepAliveCount); 187 188 return STATUS_SUCCESS; 189 } 190 191 return STATUS_NOT_FOUND; 192 } 193 194 } // extern "C" 195